Commit eb9fb5b8883535c27d2cc5d4e4dbab3532f97b18
Committed by
John W. Linville
1 parent
a02ae758e8
Exists in
master
and in
7 other branches
mac80211: trim RX data
The RX data contains the netdev, which is duplicated since we have the sdata, and the RX status pointer, which is duplicate since we have the skb. Remove those two fields to have fewer fields that depend on each other and simply load them as necessary. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 4 changed files with 61 additions and 54 deletions Inline Diff
net/mac80211/ieee80211_i.h
1 | /* | 1 | /* |
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef IEEE80211_I_H | 12 | #ifndef IEEE80211_I_H |
13 | #define IEEE80211_I_H | 13 | #define IEEE80211_I_H |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/if_ether.h> | 17 | #include <linux/if_ether.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
21 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
22 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
27 | #include <net/mac80211.h> | 27 | #include <net/mac80211.h> |
28 | #include "key.h" | 28 | #include "key.h" |
29 | #include "sta_info.h" | 29 | #include "sta_info.h" |
30 | 30 | ||
31 | struct ieee80211_local; | 31 | struct ieee80211_local; |
32 | 32 | ||
33 | /* Maximum number of broadcast/multicast frames to buffer when some of the | 33 | /* Maximum number of broadcast/multicast frames to buffer when some of the |
34 | * associated stations are using power saving. */ | 34 | * associated stations are using power saving. */ |
35 | #define AP_MAX_BC_BUFFER 128 | 35 | #define AP_MAX_BC_BUFFER 128 |
36 | 36 | ||
37 | /* Maximum number of frames buffered to all STAs, including multicast frames. | 37 | /* Maximum number of frames buffered to all STAs, including multicast frames. |
38 | * Note: increasing this limit increases the potential memory requirement. Each | 38 | * Note: increasing this limit increases the potential memory requirement. Each |
39 | * frame can be up to about 2 kB long. */ | 39 | * frame can be up to about 2 kB long. */ |
40 | #define TOTAL_MAX_TX_BUFFER 512 | 40 | #define TOTAL_MAX_TX_BUFFER 512 |
41 | 41 | ||
42 | /* Required encryption head and tailroom */ | 42 | /* Required encryption head and tailroom */ |
43 | #define IEEE80211_ENCRYPT_HEADROOM 8 | 43 | #define IEEE80211_ENCRYPT_HEADROOM 8 |
44 | #define IEEE80211_ENCRYPT_TAILROOM 18 | 44 | #define IEEE80211_ENCRYPT_TAILROOM 18 |
45 | 45 | ||
46 | /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent | 46 | /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent |
47 | * reception of at least three fragmented frames. This limit can be increased | 47 | * reception of at least three fragmented frames. This limit can be increased |
48 | * by changing this define, at the cost of slower frame reassembly and | 48 | * by changing this define, at the cost of slower frame reassembly and |
49 | * increased memory use (about 2 kB of RAM per entry). */ | 49 | * increased memory use (about 2 kB of RAM per entry). */ |
50 | #define IEEE80211_FRAGMENT_MAX 4 | 50 | #define IEEE80211_FRAGMENT_MAX 4 |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Time after which we ignore scan results and no longer report/use | 53 | * Time after which we ignore scan results and no longer report/use |
54 | * them in any way. | 54 | * them in any way. |
55 | */ | 55 | */ |
56 | #define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) | 56 | #define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) |
57 | 57 | ||
58 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) | 58 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) |
59 | 59 | ||
60 | struct ieee80211_fragment_entry { | 60 | struct ieee80211_fragment_entry { |
61 | unsigned long first_frag_time; | 61 | unsigned long first_frag_time; |
62 | unsigned int seq; | 62 | unsigned int seq; |
63 | unsigned int rx_queue; | 63 | unsigned int rx_queue; |
64 | unsigned int last_frag; | 64 | unsigned int last_frag; |
65 | unsigned int extra_len; | 65 | unsigned int extra_len; |
66 | struct sk_buff_head skb_list; | 66 | struct sk_buff_head skb_list; |
67 | int ccmp; /* Whether fragments were encrypted with CCMP */ | 67 | int ccmp; /* Whether fragments were encrypted with CCMP */ |
68 | u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ | 68 | u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |
69 | }; | 69 | }; |
70 | 70 | ||
71 | 71 | ||
72 | struct ieee80211_bss { | 72 | struct ieee80211_bss { |
73 | /* Yes, this is a hack */ | 73 | /* Yes, this is a hack */ |
74 | struct cfg80211_bss cbss; | 74 | struct cfg80211_bss cbss; |
75 | 75 | ||
76 | /* don't want to look up all the time */ | 76 | /* don't want to look up all the time */ |
77 | size_t ssid_len; | 77 | size_t ssid_len; |
78 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 78 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
79 | 79 | ||
80 | u8 dtim_period; | 80 | u8 dtim_period; |
81 | 81 | ||
82 | bool wmm_used; | 82 | bool wmm_used; |
83 | 83 | ||
84 | unsigned long last_probe_resp; | 84 | unsigned long last_probe_resp; |
85 | 85 | ||
86 | #ifdef CONFIG_MAC80211_MESH | 86 | #ifdef CONFIG_MAC80211_MESH |
87 | u8 *mesh_id; | 87 | u8 *mesh_id; |
88 | size_t mesh_id_len; | 88 | size_t mesh_id_len; |
89 | u8 *mesh_cfg; | 89 | u8 *mesh_cfg; |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #define IEEE80211_MAX_SUPP_RATES 32 | 92 | #define IEEE80211_MAX_SUPP_RATES 32 |
93 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 93 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
94 | size_t supp_rates_len; | 94 | size_t supp_rates_len; |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * During assocation, we save an ERP value from a probe response so | 97 | * During assocation, we save an ERP value from a probe response so |
98 | * that we can feed ERP info to the driver when handling the | 98 | * that we can feed ERP info to the driver when handling the |
99 | * association completes. these fields probably won't be up-to-date | 99 | * association completes. these fields probably won't be up-to-date |
100 | * otherwise, you probably don't want to use them. | 100 | * otherwise, you probably don't want to use them. |
101 | */ | 101 | */ |
102 | bool has_erp_value; | 102 | bool has_erp_value; |
103 | u8 erp_value; | 103 | u8 erp_value; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) | 106 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) |
107 | { | 107 | { |
108 | #ifdef CONFIG_MAC80211_MESH | 108 | #ifdef CONFIG_MAC80211_MESH |
109 | return bss->mesh_cfg; | 109 | return bss->mesh_cfg; |
110 | #endif | 110 | #endif |
111 | return NULL; | 111 | return NULL; |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline u8 *bss_mesh_id(struct ieee80211_bss *bss) | 114 | static inline u8 *bss_mesh_id(struct ieee80211_bss *bss) |
115 | { | 115 | { |
116 | #ifdef CONFIG_MAC80211_MESH | 116 | #ifdef CONFIG_MAC80211_MESH |
117 | return bss->mesh_id; | 117 | return bss->mesh_id; |
118 | #endif | 118 | #endif |
119 | return NULL; | 119 | return NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline u8 bss_mesh_id_len(struct ieee80211_bss *bss) | 122 | static inline u8 bss_mesh_id_len(struct ieee80211_bss *bss) |
123 | { | 123 | { |
124 | #ifdef CONFIG_MAC80211_MESH | 124 | #ifdef CONFIG_MAC80211_MESH |
125 | return bss->mesh_id_len; | 125 | return bss->mesh_id_len; |
126 | #endif | 126 | #endif |
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | 130 | ||
131 | typedef unsigned __bitwise__ ieee80211_tx_result; | 131 | typedef unsigned __bitwise__ ieee80211_tx_result; |
132 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) | 132 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) |
133 | #define TX_DROP ((__force ieee80211_tx_result) 1u) | 133 | #define TX_DROP ((__force ieee80211_tx_result) 1u) |
134 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) | 134 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) |
135 | 135 | ||
136 | #define IEEE80211_TX_FRAGMENTED BIT(0) | 136 | #define IEEE80211_TX_FRAGMENTED BIT(0) |
137 | #define IEEE80211_TX_UNICAST BIT(1) | 137 | #define IEEE80211_TX_UNICAST BIT(1) |
138 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 138 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
139 | 139 | ||
140 | struct ieee80211_tx_data { | 140 | struct ieee80211_tx_data { |
141 | struct sk_buff *skb; | 141 | struct sk_buff *skb; |
142 | struct net_device *dev; | 142 | struct net_device *dev; |
143 | struct ieee80211_local *local; | 143 | struct ieee80211_local *local; |
144 | struct ieee80211_sub_if_data *sdata; | 144 | struct ieee80211_sub_if_data *sdata; |
145 | struct sta_info *sta; | 145 | struct sta_info *sta; |
146 | struct ieee80211_key *key; | 146 | struct ieee80211_key *key; |
147 | 147 | ||
148 | struct ieee80211_channel *channel; | 148 | struct ieee80211_channel *channel; |
149 | 149 | ||
150 | u16 ethertype; | 150 | u16 ethertype; |
151 | unsigned int flags; | 151 | unsigned int flags; |
152 | }; | 152 | }; |
153 | 153 | ||
154 | 154 | ||
155 | typedef unsigned __bitwise__ ieee80211_rx_result; | 155 | typedef unsigned __bitwise__ ieee80211_rx_result; |
156 | #define RX_CONTINUE ((__force ieee80211_rx_result) 0u) | 156 | #define RX_CONTINUE ((__force ieee80211_rx_result) 0u) |
157 | #define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u) | 157 | #define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u) |
158 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | 158 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) |
159 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | 159 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) |
160 | 160 | ||
161 | #define IEEE80211_RX_IN_SCAN BIT(0) | 161 | #define IEEE80211_RX_IN_SCAN BIT(0) |
162 | /* frame is destined to interface currently processed (incl. multicast frames) */ | 162 | /* frame is destined to interface currently processed (incl. multicast frames) */ |
163 | #define IEEE80211_RX_RA_MATCH BIT(1) | 163 | #define IEEE80211_RX_RA_MATCH BIT(1) |
164 | #define IEEE80211_RX_AMSDU BIT(2) | 164 | #define IEEE80211_RX_AMSDU BIT(2) |
165 | #define IEEE80211_RX_CMNTR_REPORTED BIT(3) | 165 | #define IEEE80211_RX_CMNTR_REPORTED BIT(3) |
166 | #define IEEE80211_RX_FRAGMENTED BIT(4) | 166 | #define IEEE80211_RX_FRAGMENTED BIT(4) |
167 | 167 | ||
168 | struct ieee80211_rx_data { | 168 | struct ieee80211_rx_data { |
169 | struct sk_buff *skb; | 169 | struct sk_buff *skb; |
170 | struct net_device *dev; | ||
171 | struct ieee80211_local *local; | 170 | struct ieee80211_local *local; |
172 | struct ieee80211_sub_if_data *sdata; | 171 | struct ieee80211_sub_if_data *sdata; |
173 | struct sta_info *sta; | 172 | struct sta_info *sta; |
174 | struct ieee80211_key *key; | 173 | struct ieee80211_key *key; |
175 | struct ieee80211_rx_status *status; | ||
176 | struct ieee80211_rate *rate; | 174 | struct ieee80211_rate *rate; |
177 | 175 | ||
178 | unsigned int flags; | 176 | unsigned int flags; |
179 | int queue; | 177 | int queue; |
180 | u32 tkip_iv32; | 178 | u32 tkip_iv32; |
181 | u16 tkip_iv16; | 179 | u16 tkip_iv16; |
182 | }; | 180 | }; |
183 | 181 | ||
184 | struct beacon_data { | 182 | struct beacon_data { |
185 | u8 *head, *tail; | 183 | u8 *head, *tail; |
186 | int head_len, tail_len; | 184 | int head_len, tail_len; |
187 | int dtim_period; | 185 | int dtim_period; |
188 | }; | 186 | }; |
189 | 187 | ||
190 | struct ieee80211_if_ap { | 188 | struct ieee80211_if_ap { |
191 | struct beacon_data *beacon; | 189 | struct beacon_data *beacon; |
192 | 190 | ||
193 | struct list_head vlans; | 191 | struct list_head vlans; |
194 | 192 | ||
195 | /* yes, this looks ugly, but guarantees that we can later use | 193 | /* yes, this looks ugly, but guarantees that we can later use |
196 | * bitmap_empty :) | 194 | * bitmap_empty :) |
197 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 195 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
198 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 196 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; |
199 | struct sk_buff_head ps_bc_buf; | 197 | struct sk_buff_head ps_bc_buf; |
200 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 198 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
201 | int dtim_count; | 199 | int dtim_count; |
202 | }; | 200 | }; |
203 | 201 | ||
204 | struct ieee80211_if_wds { | 202 | struct ieee80211_if_wds { |
205 | struct sta_info *sta; | 203 | struct sta_info *sta; |
206 | u8 remote_addr[ETH_ALEN]; | 204 | u8 remote_addr[ETH_ALEN]; |
207 | }; | 205 | }; |
208 | 206 | ||
209 | struct ieee80211_if_vlan { | 207 | struct ieee80211_if_vlan { |
210 | struct list_head list; | 208 | struct list_head list; |
211 | 209 | ||
212 | /* used for all tx if the VLAN is configured to 4-addr mode */ | 210 | /* used for all tx if the VLAN is configured to 4-addr mode */ |
213 | struct sta_info *sta; | 211 | struct sta_info *sta; |
214 | }; | 212 | }; |
215 | 213 | ||
216 | struct mesh_stats { | 214 | struct mesh_stats { |
217 | __u32 fwded_mcast; /* Mesh forwarded multicast frames */ | 215 | __u32 fwded_mcast; /* Mesh forwarded multicast frames */ |
218 | __u32 fwded_unicast; /* Mesh forwarded unicast frames */ | 216 | __u32 fwded_unicast; /* Mesh forwarded unicast frames */ |
219 | __u32 fwded_frames; /* Mesh total forwarded frames */ | 217 | __u32 fwded_frames; /* Mesh total forwarded frames */ |
220 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ | 218 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ |
221 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ | 219 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ |
222 | atomic_t estab_plinks; | 220 | atomic_t estab_plinks; |
223 | }; | 221 | }; |
224 | 222 | ||
225 | #define PREQ_Q_F_START 0x1 | 223 | #define PREQ_Q_F_START 0x1 |
226 | #define PREQ_Q_F_REFRESH 0x2 | 224 | #define PREQ_Q_F_REFRESH 0x2 |
227 | struct mesh_preq_queue { | 225 | struct mesh_preq_queue { |
228 | struct list_head list; | 226 | struct list_head list; |
229 | u8 dst[ETH_ALEN]; | 227 | u8 dst[ETH_ALEN]; |
230 | u8 flags; | 228 | u8 flags; |
231 | }; | 229 | }; |
232 | 230 | ||
233 | enum ieee80211_mgd_state { | 231 | enum ieee80211_mgd_state { |
234 | IEEE80211_MGD_STATE_IDLE, | 232 | IEEE80211_MGD_STATE_IDLE, |
235 | IEEE80211_MGD_STATE_PROBE, | 233 | IEEE80211_MGD_STATE_PROBE, |
236 | IEEE80211_MGD_STATE_AUTH, | 234 | IEEE80211_MGD_STATE_AUTH, |
237 | IEEE80211_MGD_STATE_ASSOC, | 235 | IEEE80211_MGD_STATE_ASSOC, |
238 | }; | 236 | }; |
239 | 237 | ||
240 | struct ieee80211_mgd_work { | 238 | struct ieee80211_mgd_work { |
241 | struct list_head list; | 239 | struct list_head list; |
242 | struct ieee80211_bss *bss; | 240 | struct ieee80211_bss *bss; |
243 | int ie_len; | 241 | int ie_len; |
244 | u8 prev_bssid[ETH_ALEN]; | 242 | u8 prev_bssid[ETH_ALEN]; |
245 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 243 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
246 | u8 ssid_len; | 244 | u8 ssid_len; |
247 | unsigned long timeout; | 245 | unsigned long timeout; |
248 | enum ieee80211_mgd_state state; | 246 | enum ieee80211_mgd_state state; |
249 | u16 auth_alg, auth_transaction; | 247 | u16 auth_alg, auth_transaction; |
250 | 248 | ||
251 | int tries; | 249 | int tries; |
252 | 250 | ||
253 | u8 key[WLAN_KEY_LEN_WEP104]; | 251 | u8 key[WLAN_KEY_LEN_WEP104]; |
254 | u8 key_len, key_idx; | 252 | u8 key_len, key_idx; |
255 | 253 | ||
256 | /* must be last */ | 254 | /* must be last */ |
257 | u8 ie[0]; /* for auth or assoc frame, not probe */ | 255 | u8 ie[0]; /* for auth or assoc frame, not probe */ |
258 | }; | 256 | }; |
259 | 257 | ||
260 | /* flags used in struct ieee80211_if_managed.flags */ | 258 | /* flags used in struct ieee80211_if_managed.flags */ |
261 | enum ieee80211_sta_flags { | 259 | enum ieee80211_sta_flags { |
262 | IEEE80211_STA_BEACON_POLL = BIT(0), | 260 | IEEE80211_STA_BEACON_POLL = BIT(0), |
263 | IEEE80211_STA_CONNECTION_POLL = BIT(1), | 261 | IEEE80211_STA_CONNECTION_POLL = BIT(1), |
264 | IEEE80211_STA_CONTROL_PORT = BIT(2), | 262 | IEEE80211_STA_CONTROL_PORT = BIT(2), |
265 | IEEE80211_STA_WMM_ENABLED = BIT(3), | 263 | IEEE80211_STA_WMM_ENABLED = BIT(3), |
266 | IEEE80211_STA_DISABLE_11N = BIT(4), | 264 | IEEE80211_STA_DISABLE_11N = BIT(4), |
267 | IEEE80211_STA_CSA_RECEIVED = BIT(5), | 265 | IEEE80211_STA_CSA_RECEIVED = BIT(5), |
268 | IEEE80211_STA_MFP_ENABLED = BIT(6), | 266 | IEEE80211_STA_MFP_ENABLED = BIT(6), |
269 | }; | 267 | }; |
270 | 268 | ||
271 | /* flags for MLME request */ | 269 | /* flags for MLME request */ |
272 | enum ieee80211_sta_request { | 270 | enum ieee80211_sta_request { |
273 | IEEE80211_STA_REQ_SCAN, | 271 | IEEE80211_STA_REQ_SCAN, |
274 | }; | 272 | }; |
275 | 273 | ||
276 | struct ieee80211_if_managed { | 274 | struct ieee80211_if_managed { |
277 | struct timer_list timer; | 275 | struct timer_list timer; |
278 | struct timer_list conn_mon_timer; | 276 | struct timer_list conn_mon_timer; |
279 | struct timer_list bcn_mon_timer; | 277 | struct timer_list bcn_mon_timer; |
280 | struct timer_list chswitch_timer; | 278 | struct timer_list chswitch_timer; |
281 | struct work_struct work; | 279 | struct work_struct work; |
282 | struct work_struct monitor_work; | 280 | struct work_struct monitor_work; |
283 | struct work_struct chswitch_work; | 281 | struct work_struct chswitch_work; |
284 | struct work_struct beacon_loss_work; | 282 | struct work_struct beacon_loss_work; |
285 | 283 | ||
286 | unsigned long probe_timeout; | 284 | unsigned long probe_timeout; |
287 | int probe_send_count; | 285 | int probe_send_count; |
288 | 286 | ||
289 | struct mutex mtx; | 287 | struct mutex mtx; |
290 | struct ieee80211_bss *associated; | 288 | struct ieee80211_bss *associated; |
291 | struct ieee80211_mgd_work *old_associate_work; | 289 | struct ieee80211_mgd_work *old_associate_work; |
292 | struct list_head work_list; | 290 | struct list_head work_list; |
293 | 291 | ||
294 | u8 bssid[ETH_ALEN]; | 292 | u8 bssid[ETH_ALEN]; |
295 | 293 | ||
296 | u16 aid; | 294 | u16 aid; |
297 | u16 capab; | 295 | u16 capab; |
298 | 296 | ||
299 | struct sk_buff_head skb_queue; | 297 | struct sk_buff_head skb_queue; |
300 | 298 | ||
301 | unsigned long timers_running; /* used for quiesce/restart */ | 299 | unsigned long timers_running; /* used for quiesce/restart */ |
302 | bool powersave; /* powersave requested for this iface */ | 300 | bool powersave; /* powersave requested for this iface */ |
303 | 301 | ||
304 | unsigned long request; | 302 | unsigned long request; |
305 | 303 | ||
306 | unsigned int flags; | 304 | unsigned int flags; |
307 | 305 | ||
308 | u32 beacon_crc; | 306 | u32 beacon_crc; |
309 | 307 | ||
310 | enum { | 308 | enum { |
311 | IEEE80211_MFP_DISABLED, | 309 | IEEE80211_MFP_DISABLED, |
312 | IEEE80211_MFP_OPTIONAL, | 310 | IEEE80211_MFP_OPTIONAL, |
313 | IEEE80211_MFP_REQUIRED | 311 | IEEE80211_MFP_REQUIRED |
314 | } mfp; /* management frame protection */ | 312 | } mfp; /* management frame protection */ |
315 | 313 | ||
316 | int wmm_last_param_set; | 314 | int wmm_last_param_set; |
317 | }; | 315 | }; |
318 | 316 | ||
319 | enum ieee80211_ibss_request { | 317 | enum ieee80211_ibss_request { |
320 | IEEE80211_IBSS_REQ_RUN = 0, | 318 | IEEE80211_IBSS_REQ_RUN = 0, |
321 | }; | 319 | }; |
322 | 320 | ||
323 | struct ieee80211_if_ibss { | 321 | struct ieee80211_if_ibss { |
324 | struct timer_list timer; | 322 | struct timer_list timer; |
325 | struct work_struct work; | 323 | struct work_struct work; |
326 | 324 | ||
327 | struct sk_buff_head skb_queue; | 325 | struct sk_buff_head skb_queue; |
328 | 326 | ||
329 | unsigned long request; | 327 | unsigned long request; |
330 | unsigned long last_scan_completed; | 328 | unsigned long last_scan_completed; |
331 | 329 | ||
332 | bool timer_running; | 330 | bool timer_running; |
333 | 331 | ||
334 | bool fixed_bssid; | 332 | bool fixed_bssid; |
335 | bool fixed_channel; | 333 | bool fixed_channel; |
336 | bool privacy; | 334 | bool privacy; |
337 | 335 | ||
338 | u8 bssid[ETH_ALEN]; | 336 | u8 bssid[ETH_ALEN]; |
339 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 337 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
340 | u8 ssid_len, ie_len; | 338 | u8 ssid_len, ie_len; |
341 | u8 *ie; | 339 | u8 *ie; |
342 | struct ieee80211_channel *channel; | 340 | struct ieee80211_channel *channel; |
343 | 341 | ||
344 | unsigned long ibss_join_req; | 342 | unsigned long ibss_join_req; |
345 | /* probe response/beacon for IBSS */ | 343 | /* probe response/beacon for IBSS */ |
346 | struct sk_buff *presp, *skb; | 344 | struct sk_buff *presp, *skb; |
347 | 345 | ||
348 | enum { | 346 | enum { |
349 | IEEE80211_IBSS_MLME_SEARCH, | 347 | IEEE80211_IBSS_MLME_SEARCH, |
350 | IEEE80211_IBSS_MLME_JOINED, | 348 | IEEE80211_IBSS_MLME_JOINED, |
351 | } state; | 349 | } state; |
352 | }; | 350 | }; |
353 | 351 | ||
354 | struct ieee80211_if_mesh { | 352 | struct ieee80211_if_mesh { |
355 | struct work_struct work; | 353 | struct work_struct work; |
356 | struct timer_list housekeeping_timer; | 354 | struct timer_list housekeeping_timer; |
357 | struct timer_list mesh_path_timer; | 355 | struct timer_list mesh_path_timer; |
358 | struct timer_list mesh_path_root_timer; | 356 | struct timer_list mesh_path_root_timer; |
359 | struct sk_buff_head skb_queue; | 357 | struct sk_buff_head skb_queue; |
360 | 358 | ||
361 | unsigned long timers_running; | 359 | unsigned long timers_running; |
362 | 360 | ||
363 | unsigned long wrkq_flags; | 361 | unsigned long wrkq_flags; |
364 | 362 | ||
365 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; | 363 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; |
366 | size_t mesh_id_len; | 364 | size_t mesh_id_len; |
367 | /* Active Path Selection Protocol Identifier */ | 365 | /* Active Path Selection Protocol Identifier */ |
368 | u8 mesh_pp_id; | 366 | u8 mesh_pp_id; |
369 | /* Active Path Selection Metric Identifier */ | 367 | /* Active Path Selection Metric Identifier */ |
370 | u8 mesh_pm_id; | 368 | u8 mesh_pm_id; |
371 | /* Congestion Control Mode Identifier */ | 369 | /* Congestion Control Mode Identifier */ |
372 | u8 mesh_cc_id; | 370 | u8 mesh_cc_id; |
373 | /* Synchronization Protocol Identifier */ | 371 | /* Synchronization Protocol Identifier */ |
374 | u8 mesh_sp_id; | 372 | u8 mesh_sp_id; |
375 | /* Authentication Protocol Identifier */ | 373 | /* Authentication Protocol Identifier */ |
376 | u8 mesh_auth_id; | 374 | u8 mesh_auth_id; |
377 | /* Local mesh Sequence Number */ | 375 | /* Local mesh Sequence Number */ |
378 | u32 sn; | 376 | u32 sn; |
379 | /* Last used PREQ ID */ | 377 | /* Last used PREQ ID */ |
380 | u32 preq_id; | 378 | u32 preq_id; |
381 | atomic_t mpaths; | 379 | atomic_t mpaths; |
382 | /* Timestamp of last SN update */ | 380 | /* Timestamp of last SN update */ |
383 | unsigned long last_sn_update; | 381 | unsigned long last_sn_update; |
384 | /* Timestamp of last SN sent */ | 382 | /* Timestamp of last SN sent */ |
385 | unsigned long last_preq; | 383 | unsigned long last_preq; |
386 | struct mesh_rmc *rmc; | 384 | struct mesh_rmc *rmc; |
387 | spinlock_t mesh_preq_queue_lock; | 385 | spinlock_t mesh_preq_queue_lock; |
388 | struct mesh_preq_queue preq_queue; | 386 | struct mesh_preq_queue preq_queue; |
389 | int preq_queue_len; | 387 | int preq_queue_len; |
390 | struct mesh_stats mshstats; | 388 | struct mesh_stats mshstats; |
391 | struct mesh_config mshcfg; | 389 | struct mesh_config mshcfg; |
392 | u32 mesh_seqnum; | 390 | u32 mesh_seqnum; |
393 | bool accepting_plinks; | 391 | bool accepting_plinks; |
394 | }; | 392 | }; |
395 | 393 | ||
396 | #ifdef CONFIG_MAC80211_MESH | 394 | #ifdef CONFIG_MAC80211_MESH |
397 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ | 395 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ |
398 | do { (msh)->mshstats.name++; } while (0) | 396 | do { (msh)->mshstats.name++; } while (0) |
399 | #else | 397 | #else |
400 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ | 398 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ |
401 | do { } while (0) | 399 | do { } while (0) |
402 | #endif | 400 | #endif |
403 | 401 | ||
404 | /** | 402 | /** |
405 | * enum ieee80211_sub_if_data_flags - virtual interface flags | 403 | * enum ieee80211_sub_if_data_flags - virtual interface flags |
406 | * | 404 | * |
407 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets | 405 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets |
408 | * @IEEE80211_SDATA_PROMISC: interface is promisc | 406 | * @IEEE80211_SDATA_PROMISC: interface is promisc |
409 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode | 407 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode |
410 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between | 408 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between |
411 | * associated stations and deliver multicast frames both | 409 | * associated stations and deliver multicast frames both |
412 | * back to wireless media and to the local net stack. | 410 | * back to wireless media and to the local net stack. |
413 | */ | 411 | */ |
414 | enum ieee80211_sub_if_data_flags { | 412 | enum ieee80211_sub_if_data_flags { |
415 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 413 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
416 | IEEE80211_SDATA_PROMISC = BIT(1), | 414 | IEEE80211_SDATA_PROMISC = BIT(1), |
417 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 415 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
418 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 416 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
419 | }; | 417 | }; |
420 | 418 | ||
421 | struct ieee80211_sub_if_data { | 419 | struct ieee80211_sub_if_data { |
422 | struct list_head list; | 420 | struct list_head list; |
423 | 421 | ||
424 | struct wireless_dev wdev; | 422 | struct wireless_dev wdev; |
425 | 423 | ||
426 | /* keys */ | 424 | /* keys */ |
427 | struct list_head key_list; | 425 | struct list_head key_list; |
428 | 426 | ||
429 | struct net_device *dev; | 427 | struct net_device *dev; |
430 | struct ieee80211_local *local; | 428 | struct ieee80211_local *local; |
431 | 429 | ||
432 | unsigned int flags; | 430 | unsigned int flags; |
433 | 431 | ||
434 | int drop_unencrypted; | 432 | int drop_unencrypted; |
435 | 433 | ||
436 | /* | 434 | /* |
437 | * keep track of whether the HT opmode (stored in | 435 | * keep track of whether the HT opmode (stored in |
438 | * vif.bss_info.ht_operation_mode) is valid. | 436 | * vif.bss_info.ht_operation_mode) is valid. |
439 | */ | 437 | */ |
440 | bool ht_opmode_valid; | 438 | bool ht_opmode_valid; |
441 | 439 | ||
442 | /* Fragment table for host-based reassembly */ | 440 | /* Fragment table for host-based reassembly */ |
443 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 441 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
444 | unsigned int fragment_next; | 442 | unsigned int fragment_next; |
445 | 443 | ||
446 | #define NUM_DEFAULT_KEYS 4 | 444 | #define NUM_DEFAULT_KEYS 4 |
447 | #define NUM_DEFAULT_MGMT_KEYS 2 | 445 | #define NUM_DEFAULT_MGMT_KEYS 2 |
448 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; | 446 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; |
449 | struct ieee80211_key *default_key; | 447 | struct ieee80211_key *default_key; |
450 | struct ieee80211_key *default_mgmt_key; | 448 | struct ieee80211_key *default_mgmt_key; |
451 | 449 | ||
452 | u16 sequence_number; | 450 | u16 sequence_number; |
453 | 451 | ||
454 | /* | 452 | /* |
455 | * AP this belongs to: self in AP mode and | 453 | * AP this belongs to: self in AP mode and |
456 | * corresponding AP in VLAN mode, NULL for | 454 | * corresponding AP in VLAN mode, NULL for |
457 | * all others (might be needed later in IBSS) | 455 | * all others (might be needed later in IBSS) |
458 | */ | 456 | */ |
459 | struct ieee80211_if_ap *bss; | 457 | struct ieee80211_if_ap *bss; |
460 | 458 | ||
461 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | 459 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ |
462 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | 460 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ |
463 | 461 | ||
464 | bool use_4addr; /* use 4-address frames */ | 462 | bool use_4addr; /* use 4-address frames */ |
465 | 463 | ||
466 | union { | 464 | union { |
467 | struct ieee80211_if_ap ap; | 465 | struct ieee80211_if_ap ap; |
468 | struct ieee80211_if_wds wds; | 466 | struct ieee80211_if_wds wds; |
469 | struct ieee80211_if_vlan vlan; | 467 | struct ieee80211_if_vlan vlan; |
470 | struct ieee80211_if_managed mgd; | 468 | struct ieee80211_if_managed mgd; |
471 | struct ieee80211_if_ibss ibss; | 469 | struct ieee80211_if_ibss ibss; |
472 | #ifdef CONFIG_MAC80211_MESH | 470 | #ifdef CONFIG_MAC80211_MESH |
473 | struct ieee80211_if_mesh mesh; | 471 | struct ieee80211_if_mesh mesh; |
474 | #endif | 472 | #endif |
475 | u32 mntr_flags; | 473 | u32 mntr_flags; |
476 | } u; | 474 | } u; |
477 | 475 | ||
478 | #ifdef CONFIG_MAC80211_DEBUGFS | 476 | #ifdef CONFIG_MAC80211_DEBUGFS |
479 | struct { | 477 | struct { |
480 | struct dentry *dir; | 478 | struct dentry *dir; |
481 | struct dentry *default_key; | 479 | struct dentry *default_key; |
482 | struct dentry *default_mgmt_key; | 480 | struct dentry *default_mgmt_key; |
483 | } debugfs; | 481 | } debugfs; |
484 | #endif | 482 | #endif |
485 | /* must be last, dynamically sized area in this! */ | 483 | /* must be last, dynamically sized area in this! */ |
486 | struct ieee80211_vif vif; | 484 | struct ieee80211_vif vif; |
487 | }; | 485 | }; |
488 | 486 | ||
489 | static inline | 487 | static inline |
490 | struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | 488 | struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) |
491 | { | 489 | { |
492 | return container_of(p, struct ieee80211_sub_if_data, vif); | 490 | return container_of(p, struct ieee80211_sub_if_data, vif); |
493 | } | 491 | } |
494 | 492 | ||
495 | static inline void | 493 | static inline void |
496 | ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, | 494 | ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, |
497 | u8 mesh_id_len, u8 *mesh_id) | 495 | u8 mesh_id_len, u8 *mesh_id) |
498 | { | 496 | { |
499 | #ifdef CONFIG_MAC80211_MESH | 497 | #ifdef CONFIG_MAC80211_MESH |
500 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 498 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
501 | ifmsh->mesh_id_len = mesh_id_len; | 499 | ifmsh->mesh_id_len = mesh_id_len; |
502 | memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); | 500 | memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); |
503 | #else | 501 | #else |
504 | WARN_ON(1); | 502 | WARN_ON(1); |
505 | #endif | 503 | #endif |
506 | } | 504 | } |
507 | 505 | ||
508 | enum { | 506 | enum { |
509 | IEEE80211_RX_MSG = 1, | 507 | IEEE80211_RX_MSG = 1, |
510 | IEEE80211_TX_STATUS_MSG = 2, | 508 | IEEE80211_TX_STATUS_MSG = 2, |
511 | IEEE80211_DELBA_MSG = 3, | 509 | IEEE80211_DELBA_MSG = 3, |
512 | IEEE80211_ADDBA_MSG = 4, | 510 | IEEE80211_ADDBA_MSG = 4, |
513 | }; | 511 | }; |
514 | 512 | ||
515 | enum queue_stop_reason { | 513 | enum queue_stop_reason { |
516 | IEEE80211_QUEUE_STOP_REASON_DRIVER, | 514 | IEEE80211_QUEUE_STOP_REASON_DRIVER, |
517 | IEEE80211_QUEUE_STOP_REASON_PS, | 515 | IEEE80211_QUEUE_STOP_REASON_PS, |
518 | IEEE80211_QUEUE_STOP_REASON_CSA, | 516 | IEEE80211_QUEUE_STOP_REASON_CSA, |
519 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, | 517 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, |
520 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | 518 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, |
521 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | 519 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, |
522 | }; | 520 | }; |
523 | 521 | ||
524 | /** | 522 | /** |
525 | * mac80211 scan flags - currently active scan mode | 523 | * mac80211 scan flags - currently active scan mode |
526 | * | 524 | * |
527 | * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as | 525 | * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as |
528 | * well be on the operating channel | 526 | * well be on the operating channel |
529 | * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to | 527 | * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to |
530 | * determine if we are on the operating channel or not | 528 | * determine if we are on the operating channel or not |
531 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, | 529 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, |
532 | * gets only set in conjunction with SCAN_SW_SCANNING | 530 | * gets only set in conjunction with SCAN_SW_SCANNING |
533 | */ | 531 | */ |
534 | enum { | 532 | enum { |
535 | SCAN_SW_SCANNING, | 533 | SCAN_SW_SCANNING, |
536 | SCAN_HW_SCANNING, | 534 | SCAN_HW_SCANNING, |
537 | SCAN_OFF_CHANNEL, | 535 | SCAN_OFF_CHANNEL, |
538 | }; | 536 | }; |
539 | 537 | ||
540 | /** | 538 | /** |
541 | * enum mac80211_scan_state - scan state machine states | 539 | * enum mac80211_scan_state - scan state machine states |
542 | * | 540 | * |
543 | * @SCAN_DECISION: Main entry point to the scan state machine, this state | 541 | * @SCAN_DECISION: Main entry point to the scan state machine, this state |
544 | * determines if we should keep on scanning or switch back to the | 542 | * determines if we should keep on scanning or switch back to the |
545 | * operating channel | 543 | * operating channel |
546 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned | 544 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned |
547 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses | 545 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses |
548 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP | 546 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP |
549 | * about us leaving the channel and stop all associated STA interfaces | 547 | * about us leaving the channel and stop all associated STA interfaces |
550 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the | 548 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the |
551 | * AP about us being back and restart all associated STA interfaces | 549 | * AP about us being back and restart all associated STA interfaces |
552 | */ | 550 | */ |
553 | enum mac80211_scan_state { | 551 | enum mac80211_scan_state { |
554 | SCAN_DECISION, | 552 | SCAN_DECISION, |
555 | SCAN_SET_CHANNEL, | 553 | SCAN_SET_CHANNEL, |
556 | SCAN_SEND_PROBE, | 554 | SCAN_SEND_PROBE, |
557 | SCAN_LEAVE_OPER_CHANNEL, | 555 | SCAN_LEAVE_OPER_CHANNEL, |
558 | SCAN_ENTER_OPER_CHANNEL, | 556 | SCAN_ENTER_OPER_CHANNEL, |
559 | }; | 557 | }; |
560 | 558 | ||
561 | struct ieee80211_local { | 559 | struct ieee80211_local { |
562 | /* embed the driver visible part. | 560 | /* embed the driver visible part. |
563 | * don't cast (use the static inlines below), but we keep | 561 | * don't cast (use the static inlines below), but we keep |
564 | * it first anyway so they become a no-op */ | 562 | * it first anyway so they become a no-op */ |
565 | struct ieee80211_hw hw; | 563 | struct ieee80211_hw hw; |
566 | 564 | ||
567 | const struct ieee80211_ops *ops; | 565 | const struct ieee80211_ops *ops; |
568 | 566 | ||
569 | /* | 567 | /* |
570 | * private workqueue to mac80211. mac80211 makes this accessible | 568 | * private workqueue to mac80211. mac80211 makes this accessible |
571 | * via ieee80211_queue_work() | 569 | * via ieee80211_queue_work() |
572 | */ | 570 | */ |
573 | struct workqueue_struct *workqueue; | 571 | struct workqueue_struct *workqueue; |
574 | 572 | ||
575 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | 573 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; |
576 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ | 574 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ |
577 | spinlock_t queue_stop_reason_lock; | 575 | spinlock_t queue_stop_reason_lock; |
578 | 576 | ||
579 | int open_count; | 577 | int open_count; |
580 | int monitors, cooked_mntrs; | 578 | int monitors, cooked_mntrs; |
581 | /* number of interfaces with corresponding FIF_ flags */ | 579 | /* number of interfaces with corresponding FIF_ flags */ |
582 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; | 580 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; |
583 | unsigned int filter_flags; /* FIF_* */ | 581 | unsigned int filter_flags; /* FIF_* */ |
584 | struct iw_statistics wstats; | 582 | struct iw_statistics wstats; |
585 | 583 | ||
586 | /* protects the aggregated multicast list and filter calls */ | 584 | /* protects the aggregated multicast list and filter calls */ |
587 | spinlock_t filter_lock; | 585 | spinlock_t filter_lock; |
588 | 586 | ||
589 | /* used for uploading changed mc list */ | 587 | /* used for uploading changed mc list */ |
590 | struct work_struct reconfig_filter; | 588 | struct work_struct reconfig_filter; |
591 | 589 | ||
592 | /* aggregated multicast list */ | 590 | /* aggregated multicast list */ |
593 | struct dev_addr_list *mc_list; | 591 | struct dev_addr_list *mc_list; |
594 | int mc_count; | 592 | int mc_count; |
595 | 593 | ||
596 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ | 594 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ |
597 | 595 | ||
598 | /* | 596 | /* |
599 | * suspended is true if we finished all the suspend _and_ we have | 597 | * suspended is true if we finished all the suspend _and_ we have |
600 | * not yet come up from resume. This is to be used by mac80211 | 598 | * not yet come up from resume. This is to be used by mac80211 |
601 | * to ensure driver sanity during suspend and mac80211's own | 599 | * to ensure driver sanity during suspend and mac80211's own |
602 | * sanity. It can eventually be used for WoW as well. | 600 | * sanity. It can eventually be used for WoW as well. |
603 | */ | 601 | */ |
604 | bool suspended; | 602 | bool suspended; |
605 | 603 | ||
606 | /* | 604 | /* |
607 | * quiescing is true during the suspend process _only_ to | 605 | * quiescing is true during the suspend process _only_ to |
608 | * ease timer cancelling etc. | 606 | * ease timer cancelling etc. |
609 | */ | 607 | */ |
610 | bool quiescing; | 608 | bool quiescing; |
611 | 609 | ||
612 | /* device is started */ | 610 | /* device is started */ |
613 | bool started; | 611 | bool started; |
614 | 612 | ||
615 | int tx_headroom; /* required headroom for hardware/radiotap */ | 613 | int tx_headroom; /* required headroom for hardware/radiotap */ |
616 | 614 | ||
617 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 615 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
618 | * added to skb_queue will be processed, but frames in | 616 | * added to skb_queue will be processed, but frames in |
619 | * skb_queue_unreliable may be dropped if the total length of these | 617 | * skb_queue_unreliable may be dropped if the total length of these |
620 | * queues increases over the limit. */ | 618 | * queues increases over the limit. */ |
621 | #define IEEE80211_IRQSAFE_QUEUE_LIMIT 128 | 619 | #define IEEE80211_IRQSAFE_QUEUE_LIMIT 128 |
622 | struct tasklet_struct tasklet; | 620 | struct tasklet_struct tasklet; |
623 | struct sk_buff_head skb_queue; | 621 | struct sk_buff_head skb_queue; |
624 | struct sk_buff_head skb_queue_unreliable; | 622 | struct sk_buff_head skb_queue_unreliable; |
625 | 623 | ||
626 | /* Station data */ | 624 | /* Station data */ |
627 | /* | 625 | /* |
628 | * The lock only protects the list, hash, timer and counter | 626 | * The lock only protects the list, hash, timer and counter |
629 | * against manipulation, reads are done in RCU. Additionally, | 627 | * against manipulation, reads are done in RCU. Additionally, |
630 | * the lock protects each BSS's TIM bitmap. | 628 | * the lock protects each BSS's TIM bitmap. |
631 | */ | 629 | */ |
632 | spinlock_t sta_lock; | 630 | spinlock_t sta_lock; |
633 | unsigned long num_sta; | 631 | unsigned long num_sta; |
634 | struct list_head sta_list; | 632 | struct list_head sta_list; |
635 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 633 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
636 | struct timer_list sta_cleanup; | 634 | struct timer_list sta_cleanup; |
637 | int sta_generation; | 635 | int sta_generation; |
638 | 636 | ||
639 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; | 637 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; |
640 | struct tasklet_struct tx_pending_tasklet; | 638 | struct tasklet_struct tx_pending_tasklet; |
641 | 639 | ||
642 | /* | 640 | /* |
643 | * This lock is used to prevent concurrent A-MPDU | 641 | * This lock is used to prevent concurrent A-MPDU |
644 | * session start/stop processing, this thus also | 642 | * session start/stop processing, this thus also |
645 | * synchronises the ->ampdu_action() callback to | 643 | * synchronises the ->ampdu_action() callback to |
646 | * drivers and limits it to one at a time. | 644 | * drivers and limits it to one at a time. |
647 | */ | 645 | */ |
648 | spinlock_t ampdu_lock; | 646 | spinlock_t ampdu_lock; |
649 | 647 | ||
650 | /* number of interfaces with corresponding IFF_ flags */ | 648 | /* number of interfaces with corresponding IFF_ flags */ |
651 | atomic_t iff_allmultis, iff_promiscs; | 649 | atomic_t iff_allmultis, iff_promiscs; |
652 | 650 | ||
653 | struct rate_control_ref *rate_ctrl; | 651 | struct rate_control_ref *rate_ctrl; |
654 | 652 | ||
655 | struct crypto_blkcipher *wep_tx_tfm; | 653 | struct crypto_blkcipher *wep_tx_tfm; |
656 | struct crypto_blkcipher *wep_rx_tfm; | 654 | struct crypto_blkcipher *wep_rx_tfm; |
657 | u32 wep_iv; | 655 | u32 wep_iv; |
658 | 656 | ||
659 | /* see iface.c */ | 657 | /* see iface.c */ |
660 | struct list_head interfaces; | 658 | struct list_head interfaces; |
661 | struct mutex iflist_mtx; | 659 | struct mutex iflist_mtx; |
662 | 660 | ||
663 | /* | 661 | /* |
664 | * Key lock, protects sdata's key_list and sta_info's | 662 | * Key lock, protects sdata's key_list and sta_info's |
665 | * key pointers (write access, they're RCU.) | 663 | * key pointers (write access, they're RCU.) |
666 | */ | 664 | */ |
667 | spinlock_t key_lock; | 665 | spinlock_t key_lock; |
668 | 666 | ||
669 | 667 | ||
670 | /* Scanning and BSS list */ | 668 | /* Scanning and BSS list */ |
671 | struct mutex scan_mtx; | 669 | struct mutex scan_mtx; |
672 | unsigned long scanning; | 670 | unsigned long scanning; |
673 | struct cfg80211_ssid scan_ssid; | 671 | struct cfg80211_ssid scan_ssid; |
674 | struct cfg80211_scan_request *int_scan_req; | 672 | struct cfg80211_scan_request *int_scan_req; |
675 | struct cfg80211_scan_request *scan_req, *hw_scan_req; | 673 | struct cfg80211_scan_request *scan_req, *hw_scan_req; |
676 | struct ieee80211_channel *scan_channel; | 674 | struct ieee80211_channel *scan_channel; |
677 | enum ieee80211_band hw_scan_band; | 675 | enum ieee80211_band hw_scan_band; |
678 | int scan_channel_idx; | 676 | int scan_channel_idx; |
679 | int scan_ies_len; | 677 | int scan_ies_len; |
680 | 678 | ||
681 | enum mac80211_scan_state next_scan_state; | 679 | enum mac80211_scan_state next_scan_state; |
682 | struct delayed_work scan_work; | 680 | struct delayed_work scan_work; |
683 | struct ieee80211_sub_if_data *scan_sdata; | 681 | struct ieee80211_sub_if_data *scan_sdata; |
684 | enum nl80211_channel_type oper_channel_type; | 682 | enum nl80211_channel_type oper_channel_type; |
685 | struct ieee80211_channel *oper_channel, *csa_channel; | 683 | struct ieee80211_channel *oper_channel, *csa_channel; |
686 | 684 | ||
687 | /* SNMP counters */ | 685 | /* SNMP counters */ |
688 | /* dot11CountersTable */ | 686 | /* dot11CountersTable */ |
689 | u32 dot11TransmittedFragmentCount; | 687 | u32 dot11TransmittedFragmentCount; |
690 | u32 dot11MulticastTransmittedFrameCount; | 688 | u32 dot11MulticastTransmittedFrameCount; |
691 | u32 dot11FailedCount; | 689 | u32 dot11FailedCount; |
692 | u32 dot11RetryCount; | 690 | u32 dot11RetryCount; |
693 | u32 dot11MultipleRetryCount; | 691 | u32 dot11MultipleRetryCount; |
694 | u32 dot11FrameDuplicateCount; | 692 | u32 dot11FrameDuplicateCount; |
695 | u32 dot11ReceivedFragmentCount; | 693 | u32 dot11ReceivedFragmentCount; |
696 | u32 dot11MulticastReceivedFrameCount; | 694 | u32 dot11MulticastReceivedFrameCount; |
697 | u32 dot11TransmittedFrameCount; | 695 | u32 dot11TransmittedFrameCount; |
698 | 696 | ||
699 | #ifdef CONFIG_MAC80211_LEDS | 697 | #ifdef CONFIG_MAC80211_LEDS |
700 | int tx_led_counter, rx_led_counter; | 698 | int tx_led_counter, rx_led_counter; |
701 | struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; | 699 | struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; |
702 | char tx_led_name[32], rx_led_name[32], | 700 | char tx_led_name[32], rx_led_name[32], |
703 | assoc_led_name[32], radio_led_name[32]; | 701 | assoc_led_name[32], radio_led_name[32]; |
704 | #endif | 702 | #endif |
705 | 703 | ||
706 | #ifdef CONFIG_MAC80211_DEBUGFS | 704 | #ifdef CONFIG_MAC80211_DEBUGFS |
707 | struct work_struct sta_debugfs_add; | 705 | struct work_struct sta_debugfs_add; |
708 | #endif | 706 | #endif |
709 | 707 | ||
710 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 708 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
711 | /* TX/RX handler statistics */ | 709 | /* TX/RX handler statistics */ |
712 | unsigned int tx_handlers_drop; | 710 | unsigned int tx_handlers_drop; |
713 | unsigned int tx_handlers_queued; | 711 | unsigned int tx_handlers_queued; |
714 | unsigned int tx_handlers_drop_unencrypted; | 712 | unsigned int tx_handlers_drop_unencrypted; |
715 | unsigned int tx_handlers_drop_fragment; | 713 | unsigned int tx_handlers_drop_fragment; |
716 | unsigned int tx_handlers_drop_wep; | 714 | unsigned int tx_handlers_drop_wep; |
717 | unsigned int tx_handlers_drop_not_assoc; | 715 | unsigned int tx_handlers_drop_not_assoc; |
718 | unsigned int tx_handlers_drop_unauth_port; | 716 | unsigned int tx_handlers_drop_unauth_port; |
719 | unsigned int rx_handlers_drop; | 717 | unsigned int rx_handlers_drop; |
720 | unsigned int rx_handlers_queued; | 718 | unsigned int rx_handlers_queued; |
721 | unsigned int rx_handlers_drop_nullfunc; | 719 | unsigned int rx_handlers_drop_nullfunc; |
722 | unsigned int rx_handlers_drop_defrag; | 720 | unsigned int rx_handlers_drop_defrag; |
723 | unsigned int rx_handlers_drop_short; | 721 | unsigned int rx_handlers_drop_short; |
724 | unsigned int rx_handlers_drop_passive_scan; | 722 | unsigned int rx_handlers_drop_passive_scan; |
725 | unsigned int tx_expand_skb_head; | 723 | unsigned int tx_expand_skb_head; |
726 | unsigned int tx_expand_skb_head_cloned; | 724 | unsigned int tx_expand_skb_head_cloned; |
727 | unsigned int rx_expand_skb_head; | 725 | unsigned int rx_expand_skb_head; |
728 | unsigned int rx_expand_skb_head2; | 726 | unsigned int rx_expand_skb_head2; |
729 | unsigned int rx_handlers_fragments; | 727 | unsigned int rx_handlers_fragments; |
730 | unsigned int tx_status_drop; | 728 | unsigned int tx_status_drop; |
731 | #define I802_DEBUG_INC(c) (c)++ | 729 | #define I802_DEBUG_INC(c) (c)++ |
732 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 730 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
733 | #define I802_DEBUG_INC(c) do { } while (0) | 731 | #define I802_DEBUG_INC(c) do { } while (0) |
734 | #endif /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 732 | #endif /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
735 | 733 | ||
736 | 734 | ||
737 | int total_ps_buffered; /* total number of all buffered unicast and | 735 | int total_ps_buffered; /* total number of all buffered unicast and |
738 | * multicast packets for power saving stations | 736 | * multicast packets for power saving stations |
739 | */ | 737 | */ |
740 | int wifi_wme_noack_test; | 738 | int wifi_wme_noack_test; |
741 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 739 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
742 | 740 | ||
743 | bool pspolling; | 741 | bool pspolling; |
744 | /* | 742 | /* |
745 | * PS can only be enabled when we have exactly one managed | 743 | * PS can only be enabled when we have exactly one managed |
746 | * interface (and monitors) in PS, this then points there. | 744 | * interface (and monitors) in PS, this then points there. |
747 | */ | 745 | */ |
748 | struct ieee80211_sub_if_data *ps_sdata; | 746 | struct ieee80211_sub_if_data *ps_sdata; |
749 | struct work_struct dynamic_ps_enable_work; | 747 | struct work_struct dynamic_ps_enable_work; |
750 | struct work_struct dynamic_ps_disable_work; | 748 | struct work_struct dynamic_ps_disable_work; |
751 | struct timer_list dynamic_ps_timer; | 749 | struct timer_list dynamic_ps_timer; |
752 | struct notifier_block network_latency_notifier; | 750 | struct notifier_block network_latency_notifier; |
753 | 751 | ||
754 | int user_power_level; /* in dBm */ | 752 | int user_power_level; /* in dBm */ |
755 | int power_constr_level; /* in dBm */ | 753 | int power_constr_level; /* in dBm */ |
756 | 754 | ||
757 | struct work_struct restart_work; | 755 | struct work_struct restart_work; |
758 | 756 | ||
759 | #ifdef CONFIG_MAC80211_DEBUGFS | 757 | #ifdef CONFIG_MAC80211_DEBUGFS |
760 | struct local_debugfsdentries { | 758 | struct local_debugfsdentries { |
761 | struct dentry *rcdir; | 759 | struct dentry *rcdir; |
762 | struct dentry *stations; | 760 | struct dentry *stations; |
763 | struct dentry *keys; | 761 | struct dentry *keys; |
764 | } debugfs; | 762 | } debugfs; |
765 | #endif | 763 | #endif |
766 | }; | 764 | }; |
767 | 765 | ||
768 | static inline struct ieee80211_sub_if_data * | 766 | static inline struct ieee80211_sub_if_data * |
769 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | 767 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) |
770 | { | 768 | { |
771 | return netdev_priv(dev); | 769 | return netdev_priv(dev); |
772 | } | 770 | } |
773 | 771 | ||
774 | /* this struct represents 802.11n's RA/TID combination along with our vif */ | 772 | /* this struct represents 802.11n's RA/TID combination along with our vif */ |
775 | struct ieee80211_ra_tid { | 773 | struct ieee80211_ra_tid { |
776 | struct ieee80211_vif *vif; | 774 | struct ieee80211_vif *vif; |
777 | u8 ra[ETH_ALEN]; | 775 | u8 ra[ETH_ALEN]; |
778 | u16 tid; | 776 | u16 tid; |
779 | }; | 777 | }; |
780 | 778 | ||
781 | /* Parsed Information Elements */ | 779 | /* Parsed Information Elements */ |
782 | struct ieee802_11_elems { | 780 | struct ieee802_11_elems { |
783 | u8 *ie_start; | 781 | u8 *ie_start; |
784 | size_t total_len; | 782 | size_t total_len; |
785 | 783 | ||
786 | /* pointers to IEs */ | 784 | /* pointers to IEs */ |
787 | u8 *ssid; | 785 | u8 *ssid; |
788 | u8 *supp_rates; | 786 | u8 *supp_rates; |
789 | u8 *fh_params; | 787 | u8 *fh_params; |
790 | u8 *ds_params; | 788 | u8 *ds_params; |
791 | u8 *cf_params; | 789 | u8 *cf_params; |
792 | struct ieee80211_tim_ie *tim; | 790 | struct ieee80211_tim_ie *tim; |
793 | u8 *ibss_params; | 791 | u8 *ibss_params; |
794 | u8 *challenge; | 792 | u8 *challenge; |
795 | u8 *wpa; | 793 | u8 *wpa; |
796 | u8 *rsn; | 794 | u8 *rsn; |
797 | u8 *erp_info; | 795 | u8 *erp_info; |
798 | u8 *ext_supp_rates; | 796 | u8 *ext_supp_rates; |
799 | u8 *wmm_info; | 797 | u8 *wmm_info; |
800 | u8 *wmm_param; | 798 | u8 *wmm_param; |
801 | struct ieee80211_ht_cap *ht_cap_elem; | 799 | struct ieee80211_ht_cap *ht_cap_elem; |
802 | struct ieee80211_ht_info *ht_info_elem; | 800 | struct ieee80211_ht_info *ht_info_elem; |
803 | u8 *mesh_config; | 801 | u8 *mesh_config; |
804 | u8 *mesh_id; | 802 | u8 *mesh_id; |
805 | u8 *peer_link; | 803 | u8 *peer_link; |
806 | u8 *preq; | 804 | u8 *preq; |
807 | u8 *prep; | 805 | u8 *prep; |
808 | u8 *perr; | 806 | u8 *perr; |
809 | struct ieee80211_rann_ie *rann; | 807 | struct ieee80211_rann_ie *rann; |
810 | u8 *ch_switch_elem; | 808 | u8 *ch_switch_elem; |
811 | u8 *country_elem; | 809 | u8 *country_elem; |
812 | u8 *pwr_constr_elem; | 810 | u8 *pwr_constr_elem; |
813 | u8 *quiet_elem; /* first quite element */ | 811 | u8 *quiet_elem; /* first quite element */ |
814 | u8 *timeout_int; | 812 | u8 *timeout_int; |
815 | 813 | ||
816 | /* length of them, respectively */ | 814 | /* length of them, respectively */ |
817 | u8 ssid_len; | 815 | u8 ssid_len; |
818 | u8 supp_rates_len; | 816 | u8 supp_rates_len; |
819 | u8 fh_params_len; | 817 | u8 fh_params_len; |
820 | u8 ds_params_len; | 818 | u8 ds_params_len; |
821 | u8 cf_params_len; | 819 | u8 cf_params_len; |
822 | u8 tim_len; | 820 | u8 tim_len; |
823 | u8 ibss_params_len; | 821 | u8 ibss_params_len; |
824 | u8 challenge_len; | 822 | u8 challenge_len; |
825 | u8 wpa_len; | 823 | u8 wpa_len; |
826 | u8 rsn_len; | 824 | u8 rsn_len; |
827 | u8 erp_info_len; | 825 | u8 erp_info_len; |
828 | u8 ext_supp_rates_len; | 826 | u8 ext_supp_rates_len; |
829 | u8 wmm_info_len; | 827 | u8 wmm_info_len; |
830 | u8 wmm_param_len; | 828 | u8 wmm_param_len; |
831 | u8 mesh_config_len; | 829 | u8 mesh_config_len; |
832 | u8 mesh_id_len; | 830 | u8 mesh_id_len; |
833 | u8 peer_link_len; | 831 | u8 peer_link_len; |
834 | u8 preq_len; | 832 | u8 preq_len; |
835 | u8 prep_len; | 833 | u8 prep_len; |
836 | u8 perr_len; | 834 | u8 perr_len; |
837 | u8 ch_switch_elem_len; | 835 | u8 ch_switch_elem_len; |
838 | u8 country_elem_len; | 836 | u8 country_elem_len; |
839 | u8 pwr_constr_elem_len; | 837 | u8 pwr_constr_elem_len; |
840 | u8 quiet_elem_len; | 838 | u8 quiet_elem_len; |
841 | u8 num_of_quiet_elem; /* can be more the one */ | 839 | u8 num_of_quiet_elem; /* can be more the one */ |
842 | u8 timeout_int_len; | 840 | u8 timeout_int_len; |
843 | }; | 841 | }; |
844 | 842 | ||
845 | static inline struct ieee80211_local *hw_to_local( | 843 | static inline struct ieee80211_local *hw_to_local( |
846 | struct ieee80211_hw *hw) | 844 | struct ieee80211_hw *hw) |
847 | { | 845 | { |
848 | return container_of(hw, struct ieee80211_local, hw); | 846 | return container_of(hw, struct ieee80211_local, hw); |
849 | } | 847 | } |
850 | 848 | ||
851 | static inline struct ieee80211_hw *local_to_hw( | 849 | static inline struct ieee80211_hw *local_to_hw( |
852 | struct ieee80211_local *local) | 850 | struct ieee80211_local *local) |
853 | { | 851 | { |
854 | return &local->hw; | 852 | return &local->hw; |
855 | } | 853 | } |
856 | 854 | ||
857 | 855 | ||
858 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 856 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
859 | { | 857 | { |
860 | return compare_ether_addr(raddr, addr) == 0 || | 858 | return compare_ether_addr(raddr, addr) == 0 || |
861 | is_broadcast_ether_addr(raddr); | 859 | is_broadcast_ether_addr(raddr); |
862 | } | 860 | } |
863 | 861 | ||
864 | 862 | ||
865 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); | 863 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); |
866 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 864 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
867 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 865 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
868 | u32 changed); | 866 | u32 changed); |
869 | void ieee80211_configure_filter(struct ieee80211_local *local); | 867 | void ieee80211_configure_filter(struct ieee80211_local *local); |
870 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 868 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
871 | 869 | ||
872 | /* STA code */ | 870 | /* STA code */ |
873 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 871 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
874 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 872 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
875 | struct cfg80211_auth_request *req); | 873 | struct cfg80211_auth_request *req); |
876 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | 874 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, |
877 | struct cfg80211_assoc_request *req); | 875 | struct cfg80211_assoc_request *req); |
878 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | 876 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, |
879 | struct cfg80211_deauth_request *req, | 877 | struct cfg80211_deauth_request *req, |
880 | void *cookie); | 878 | void *cookie); |
881 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | 879 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, |
882 | struct cfg80211_disassoc_request *req, | 880 | struct cfg80211_disassoc_request *req, |
883 | void *cookie); | 881 | void *cookie); |
884 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | 882 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, |
885 | struct sk_buff *skb); | 883 | struct sk_buff *skb); |
886 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 884 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
887 | struct ieee80211_sub_if_data *sdata); | 885 | struct ieee80211_sub_if_data *sdata); |
888 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); | 886 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); |
889 | int ieee80211_max_network_latency(struct notifier_block *nb, | 887 | int ieee80211_max_network_latency(struct notifier_block *nb, |
890 | unsigned long data, void *dummy); | 888 | unsigned long data, void *dummy); |
891 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 889 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
892 | struct ieee80211_channel_sw_ie *sw_elem, | 890 | struct ieee80211_channel_sw_ie *sw_elem, |
893 | struct ieee80211_bss *bss); | 891 | struct ieee80211_bss *bss); |
894 | void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); | 892 | void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); |
895 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); | 893 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); |
896 | 894 | ||
897 | /* IBSS code */ | 895 | /* IBSS code */ |
898 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 896 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
899 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); | 897 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); |
900 | ieee80211_rx_result | 898 | ieee80211_rx_result |
901 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 899 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
902 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 900 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
903 | u8 *bssid, u8 *addr, u32 supp_rates); | 901 | u8 *bssid, u8 *addr, u32 supp_rates); |
904 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | 902 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, |
905 | struct cfg80211_ibss_params *params); | 903 | struct cfg80211_ibss_params *params); |
906 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); | 904 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); |
907 | void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata); | 905 | void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata); |
908 | void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); | 906 | void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); |
909 | 907 | ||
910 | /* scan/BSS handling */ | 908 | /* scan/BSS handling */ |
911 | void ieee80211_scan_work(struct work_struct *work); | 909 | void ieee80211_scan_work(struct work_struct *work); |
912 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 910 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
913 | const u8 *ssid, u8 ssid_len); | 911 | const u8 *ssid, u8 ssid_len); |
914 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 912 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
915 | struct cfg80211_scan_request *req); | 913 | struct cfg80211_scan_request *req); |
916 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 914 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
917 | ieee80211_rx_result | 915 | ieee80211_rx_result |
918 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 916 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
919 | 917 | ||
920 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); | 918 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); |
921 | struct ieee80211_bss * | 919 | struct ieee80211_bss * |
922 | ieee80211_bss_info_update(struct ieee80211_local *local, | 920 | ieee80211_bss_info_update(struct ieee80211_local *local, |
923 | struct ieee80211_rx_status *rx_status, | 921 | struct ieee80211_rx_status *rx_status, |
924 | struct ieee80211_mgmt *mgmt, | 922 | struct ieee80211_mgmt *mgmt, |
925 | size_t len, | 923 | size_t len, |
926 | struct ieee802_11_elems *elems, | 924 | struct ieee802_11_elems *elems, |
927 | struct ieee80211_channel *channel, | 925 | struct ieee80211_channel *channel, |
928 | bool beacon); | 926 | bool beacon); |
929 | struct ieee80211_bss * | 927 | struct ieee80211_bss * |
930 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, | 928 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, |
931 | u8 *ssid, u8 ssid_len); | 929 | u8 *ssid, u8 ssid_len); |
932 | void ieee80211_rx_bss_put(struct ieee80211_local *local, | 930 | void ieee80211_rx_bss_put(struct ieee80211_local *local, |
933 | struct ieee80211_bss *bss); | 931 | struct ieee80211_bss *bss); |
934 | 932 | ||
935 | /* interface handling */ | 933 | /* interface handling */ |
936 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 934 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
937 | struct net_device **new_dev, enum nl80211_iftype type, | 935 | struct net_device **new_dev, enum nl80211_iftype type, |
938 | struct vif_params *params); | 936 | struct vif_params *params); |
939 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 937 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
940 | enum nl80211_iftype type); | 938 | enum nl80211_iftype type); |
941 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 939 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
942 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 940 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
943 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | 941 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); |
944 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 942 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
945 | 943 | ||
946 | /* tx handling */ | 944 | /* tx handling */ |
947 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); | 945 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); |
948 | void ieee80211_tx_pending(unsigned long data); | 946 | void ieee80211_tx_pending(unsigned long data); |
949 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | 947 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, |
950 | struct net_device *dev); | 948 | struct net_device *dev); |
951 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | 949 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, |
952 | struct net_device *dev); | 950 | struct net_device *dev); |
953 | 951 | ||
954 | /* HT */ | 952 | /* HT */ |
955 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, | 953 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
956 | struct ieee80211_ht_cap *ht_cap_ie, | 954 | struct ieee80211_ht_cap *ht_cap_ie, |
957 | struct ieee80211_sta_ht_cap *ht_cap); | 955 | struct ieee80211_sta_ht_cap *ht_cap); |
958 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); | 956 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); |
959 | void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | 957 | void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, |
960 | const u8 *da, u16 tid, | 958 | const u8 *da, u16 tid, |
961 | u16 initiator, u16 reason_code); | 959 | u16 initiator, u16 reason_code); |
962 | 960 | ||
963 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, | 961 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, |
964 | u16 tid, u16 initiator, u16 reason); | 962 | u16 tid, u16 initiator, u16 reason); |
965 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 963 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
966 | u16 initiator, u16 reason); | 964 | u16 initiator, u16 reason); |
967 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); | 965 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); |
968 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | 966 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, |
969 | struct sta_info *sta, | 967 | struct sta_info *sta, |
970 | struct ieee80211_mgmt *mgmt, size_t len); | 968 | struct ieee80211_mgmt *mgmt, size_t len); |
971 | void ieee80211_process_addba_resp(struct ieee80211_local *local, | 969 | void ieee80211_process_addba_resp(struct ieee80211_local *local, |
972 | struct sta_info *sta, | 970 | struct sta_info *sta, |
973 | struct ieee80211_mgmt *mgmt, | 971 | struct ieee80211_mgmt *mgmt, |
974 | size_t len); | 972 | size_t len); |
975 | void ieee80211_process_addba_request(struct ieee80211_local *local, | 973 | void ieee80211_process_addba_request(struct ieee80211_local *local, |
976 | struct sta_info *sta, | 974 | struct sta_info *sta, |
977 | struct ieee80211_mgmt *mgmt, | 975 | struct ieee80211_mgmt *mgmt, |
978 | size_t len); | 976 | size_t len); |
979 | 977 | ||
980 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 978 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
981 | enum ieee80211_back_parties initiator); | 979 | enum ieee80211_back_parties initiator); |
982 | 980 | ||
983 | /* Spectrum management */ | 981 | /* Spectrum management */ |
984 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 982 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
985 | struct ieee80211_mgmt *mgmt, | 983 | struct ieee80211_mgmt *mgmt, |
986 | size_t len); | 984 | size_t len); |
987 | 985 | ||
988 | /* Suspend/resume and hw reconfiguration */ | 986 | /* Suspend/resume and hw reconfiguration */ |
989 | int ieee80211_reconfig(struct ieee80211_local *local); | 987 | int ieee80211_reconfig(struct ieee80211_local *local); |
990 | void ieee80211_stop_device(struct ieee80211_local *local); | 988 | void ieee80211_stop_device(struct ieee80211_local *local); |
991 | 989 | ||
992 | #ifdef CONFIG_PM | 990 | #ifdef CONFIG_PM |
993 | int __ieee80211_suspend(struct ieee80211_hw *hw); | 991 | int __ieee80211_suspend(struct ieee80211_hw *hw); |
994 | 992 | ||
995 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) | 993 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) |
996 | { | 994 | { |
997 | return ieee80211_reconfig(hw_to_local(hw)); | 995 | return ieee80211_reconfig(hw_to_local(hw)); |
998 | } | 996 | } |
999 | #else | 997 | #else |
1000 | static inline int __ieee80211_suspend(struct ieee80211_hw *hw) | 998 | static inline int __ieee80211_suspend(struct ieee80211_hw *hw) |
1001 | { | 999 | { |
1002 | return 0; | 1000 | return 0; |
1003 | } | 1001 | } |
1004 | 1002 | ||
1005 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) | 1003 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) |
1006 | { | 1004 | { |
1007 | return 0; | 1005 | return 0; |
1008 | } | 1006 | } |
1009 | #endif | 1007 | #endif |
1010 | 1008 | ||
1011 | /* utility functions/constants */ | 1009 | /* utility functions/constants */ |
1012 | extern void *mac80211_wiphy_privid; /* for wiphy privid */ | 1010 | extern void *mac80211_wiphy_privid; /* for wiphy privid */ |
1013 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 1011 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
1014 | enum nl80211_iftype type); | 1012 | enum nl80211_iftype type); |
1015 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | 1013 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, |
1016 | int rate, int erp, int short_preamble); | 1014 | int rate, int erp, int short_preamble); |
1017 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, | 1015 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, |
1018 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1016 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1019 | gfp_t gfp); | 1017 | gfp_t gfp); |
1020 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1018 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); |
1021 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 1019 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, |
1022 | int encrypt); | 1020 | int encrypt); |
1023 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1021 | void ieee802_11_parse_elems(u8 *start, size_t len, |
1024 | struct ieee802_11_elems *elems); | 1022 | struct ieee802_11_elems *elems); |
1025 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 1023 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, |
1026 | struct ieee802_11_elems *elems, | 1024 | struct ieee802_11_elems *elems, |
1027 | u64 filter, u32 crc); | 1025 | u64 filter, u32 crc); |
1028 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 1026 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
1029 | enum ieee80211_band band); | 1027 | enum ieee80211_band band); |
1030 | 1028 | ||
1031 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); | 1029 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); |
1032 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); | 1030 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); |
1033 | void ieee80211_dynamic_ps_timer(unsigned long data); | 1031 | void ieee80211_dynamic_ps_timer(unsigned long data); |
1034 | void ieee80211_send_nullfunc(struct ieee80211_local *local, | 1032 | void ieee80211_send_nullfunc(struct ieee80211_local *local, |
1035 | struct ieee80211_sub_if_data *sdata, | 1033 | struct ieee80211_sub_if_data *sdata, |
1036 | int powersave); | 1034 | int powersave); |
1037 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1035 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, |
1038 | struct ieee80211_hdr *hdr); | 1036 | struct ieee80211_hdr *hdr); |
1039 | void ieee80211_beacon_loss_work(struct work_struct *work); | 1037 | void ieee80211_beacon_loss_work(struct work_struct *work); |
1040 | 1038 | ||
1041 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 1039 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
1042 | enum queue_stop_reason reason); | 1040 | enum queue_stop_reason reason); |
1043 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 1041 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
1044 | enum queue_stop_reason reason); | 1042 | enum queue_stop_reason reason); |
1045 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1043 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1046 | enum queue_stop_reason reason); | 1044 | enum queue_stop_reason reason); |
1047 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1045 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1048 | enum queue_stop_reason reason); | 1046 | enum queue_stop_reason reason); |
1049 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1047 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
1050 | struct sk_buff *skb); | 1048 | struct sk_buff *skb); |
1051 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 1049 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1052 | struct sk_buff_head *skbs); | 1050 | struct sk_buff_head *skbs); |
1053 | 1051 | ||
1054 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1052 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1055 | u16 transaction, u16 auth_alg, | 1053 | u16 transaction, u16 auth_alg, |
1056 | u8 *extra, size_t extra_len, const u8 *bssid, | 1054 | u8 *extra, size_t extra_len, const u8 *bssid, |
1057 | const u8 *key, u8 key_len, u8 key_idx); | 1055 | const u8 *key, u8 key_len, u8 key_idx); |
1058 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1056 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1059 | const u8 *ie, size_t ie_len, | 1057 | const u8 *ie, size_t ie_len, |
1060 | enum ieee80211_band band); | 1058 | enum ieee80211_band band); |
1061 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1059 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1062 | const u8 *ssid, size_t ssid_len, | 1060 | const u8 *ssid, size_t ssid_len, |
1063 | const u8 *ie, size_t ie_len); | 1061 | const u8 *ie, size_t ie_len); |
1064 | 1062 | ||
1065 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 1063 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
1066 | const size_t supp_rates_len, | 1064 | const size_t supp_rates_len, |
1067 | const u8 *supp_rates); | 1065 | const u8 *supp_rates); |
1068 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 1066 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, |
1069 | struct ieee802_11_elems *elems, | 1067 | struct ieee802_11_elems *elems, |
1070 | enum ieee80211_band band); | 1068 | enum ieee80211_band band); |
1071 | 1069 | ||
1072 | #ifdef CONFIG_MAC80211_NOINLINE | 1070 | #ifdef CONFIG_MAC80211_NOINLINE |
1073 | #define debug_noinline noinline | 1071 | #define debug_noinline noinline |
1074 | #else | 1072 | #else |
1075 | #define debug_noinline | 1073 | #define debug_noinline |
1076 | #endif | 1074 | #endif |
1077 | 1075 | ||
1078 | #endif /* IEEE80211_I_H */ | 1076 | #endif /* IEEE80211_I_H */ |
1079 | 1077 |
net/mac80211/rx.c
1 | /* | 1 | /* |
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/jiffies.h> | 12 | #include <linux/jiffies.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
17 | #include <linux/rcupdate.h> | 17 | #include <linux/rcupdate.h> |
18 | #include <net/mac80211.h> | 18 | #include <net/mac80211.h> |
19 | #include <net/ieee80211_radiotap.h> | 19 | #include <net/ieee80211_radiotap.h> |
20 | 20 | ||
21 | #include "ieee80211_i.h" | 21 | #include "ieee80211_i.h" |
22 | #include "driver-ops.h" | 22 | #include "driver-ops.h" |
23 | #include "led.h" | 23 | #include "led.h" |
24 | #include "mesh.h" | 24 | #include "mesh.h" |
25 | #include "wep.h" | 25 | #include "wep.h" |
26 | #include "wpa.h" | 26 | #include "wpa.h" |
27 | #include "tkip.h" | 27 | #include "tkip.h" |
28 | #include "wme.h" | 28 | #include "wme.h" |
29 | 29 | ||
30 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | 30 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, |
31 | struct tid_ampdu_rx *tid_agg_rx, | 31 | struct tid_ampdu_rx *tid_agg_rx, |
32 | u16 head_seq_num); | 32 | u16 head_seq_num); |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * monitor mode reception | 35 | * monitor mode reception |
36 | * | 36 | * |
37 | * This function cleans up the SKB, i.e. it removes all the stuff | 37 | * This function cleans up the SKB, i.e. it removes all the stuff |
38 | * only useful for monitoring. | 38 | * only useful for monitoring. |
39 | */ | 39 | */ |
40 | static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, | 40 | static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, |
41 | struct sk_buff *skb) | 41 | struct sk_buff *skb) |
42 | { | 42 | { |
43 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { | 43 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { |
44 | if (likely(skb->len > FCS_LEN)) | 44 | if (likely(skb->len > FCS_LEN)) |
45 | skb_trim(skb, skb->len - FCS_LEN); | 45 | skb_trim(skb, skb->len - FCS_LEN); |
46 | else { | 46 | else { |
47 | /* driver bug */ | 47 | /* driver bug */ |
48 | WARN_ON(1); | 48 | WARN_ON(1); |
49 | dev_kfree_skb(skb); | 49 | dev_kfree_skb(skb); |
50 | skb = NULL; | 50 | skb = NULL; |
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | return skb; | 54 | return skb; |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline int should_drop_frame(struct sk_buff *skb, | 57 | static inline int should_drop_frame(struct sk_buff *skb, |
58 | int present_fcs_len) | 58 | int present_fcs_len) |
59 | { | 59 | { |
60 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 60 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
61 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 61 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
62 | 62 | ||
63 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | 63 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) |
64 | return 1; | 64 | return 1; |
65 | if (unlikely(skb->len < 16 + present_fcs_len)) | 65 | if (unlikely(skb->len < 16 + present_fcs_len)) |
66 | return 1; | 66 | return 1; |
67 | if (ieee80211_is_ctl(hdr->frame_control) && | 67 | if (ieee80211_is_ctl(hdr->frame_control) && |
68 | !ieee80211_is_pspoll(hdr->frame_control) && | 68 | !ieee80211_is_pspoll(hdr->frame_control) && |
69 | !ieee80211_is_back_req(hdr->frame_control)) | 69 | !ieee80211_is_back_req(hdr->frame_control)) |
70 | return 1; | 70 | return 1; |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int | 74 | static int |
75 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, | 75 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, |
76 | struct ieee80211_rx_status *status) | 76 | struct ieee80211_rx_status *status) |
77 | { | 77 | { |
78 | int len; | 78 | int len; |
79 | 79 | ||
80 | /* always present fields */ | 80 | /* always present fields */ |
81 | len = sizeof(struct ieee80211_radiotap_header) + 9; | 81 | len = sizeof(struct ieee80211_radiotap_header) + 9; |
82 | 82 | ||
83 | if (status->flag & RX_FLAG_TSFT) | 83 | if (status->flag & RX_FLAG_TSFT) |
84 | len += 8; | 84 | len += 8; |
85 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 85 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
86 | len += 1; | 86 | len += 1; |
87 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | 87 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) |
88 | len += 1; | 88 | len += 1; |
89 | 89 | ||
90 | if (len & 1) /* padding for RX_FLAGS if necessary */ | 90 | if (len & 1) /* padding for RX_FLAGS if necessary */ |
91 | len++; | 91 | len++; |
92 | 92 | ||
93 | return len; | 93 | return len; |
94 | } | 94 | } |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * ieee80211_add_rx_radiotap_header - add radiotap header | 97 | * ieee80211_add_rx_radiotap_header - add radiotap header |
98 | * | 98 | * |
99 | * add a radiotap header containing all the fields which the hardware provided. | 99 | * add a radiotap header containing all the fields which the hardware provided. |
100 | */ | 100 | */ |
101 | static void | 101 | static void |
102 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | 102 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, |
103 | struct sk_buff *skb, | 103 | struct sk_buff *skb, |
104 | struct ieee80211_rate *rate, | 104 | struct ieee80211_rate *rate, |
105 | int rtap_len) | 105 | int rtap_len) |
106 | { | 106 | { |
107 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 107 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
108 | struct ieee80211_radiotap_header *rthdr; | 108 | struct ieee80211_radiotap_header *rthdr; |
109 | unsigned char *pos; | 109 | unsigned char *pos; |
110 | u16 rx_flags = 0; | 110 | u16 rx_flags = 0; |
111 | 111 | ||
112 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | 112 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); |
113 | memset(rthdr, 0, rtap_len); | 113 | memset(rthdr, 0, rtap_len); |
114 | 114 | ||
115 | /* radiotap header, set always present flags */ | 115 | /* radiotap header, set always present flags */ |
116 | rthdr->it_present = | 116 | rthdr->it_present = |
117 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 117 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
118 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 118 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
119 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | 119 | (1 << IEEE80211_RADIOTAP_ANTENNA) | |
120 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | 120 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); |
121 | rthdr->it_len = cpu_to_le16(rtap_len); | 121 | rthdr->it_len = cpu_to_le16(rtap_len); |
122 | 122 | ||
123 | pos = (unsigned char *)(rthdr+1); | 123 | pos = (unsigned char *)(rthdr+1); |
124 | 124 | ||
125 | /* the order of the following fields is important */ | 125 | /* the order of the following fields is important */ |
126 | 126 | ||
127 | /* IEEE80211_RADIOTAP_TSFT */ | 127 | /* IEEE80211_RADIOTAP_TSFT */ |
128 | if (status->flag & RX_FLAG_TSFT) { | 128 | if (status->flag & RX_FLAG_TSFT) { |
129 | put_unaligned_le64(status->mactime, pos); | 129 | put_unaligned_le64(status->mactime, pos); |
130 | rthdr->it_present |= | 130 | rthdr->it_present |= |
131 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | 131 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); |
132 | pos += 8; | 132 | pos += 8; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* IEEE80211_RADIOTAP_FLAGS */ | 135 | /* IEEE80211_RADIOTAP_FLAGS */ |
136 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 136 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
137 | *pos |= IEEE80211_RADIOTAP_F_FCS; | 137 | *pos |= IEEE80211_RADIOTAP_F_FCS; |
138 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | 138 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) |
139 | *pos |= IEEE80211_RADIOTAP_F_BADFCS; | 139 | *pos |= IEEE80211_RADIOTAP_F_BADFCS; |
140 | if (status->flag & RX_FLAG_SHORTPRE) | 140 | if (status->flag & RX_FLAG_SHORTPRE) |
141 | *pos |= IEEE80211_RADIOTAP_F_SHORTPRE; | 141 | *pos |= IEEE80211_RADIOTAP_F_SHORTPRE; |
142 | pos++; | 142 | pos++; |
143 | 143 | ||
144 | /* IEEE80211_RADIOTAP_RATE */ | 144 | /* IEEE80211_RADIOTAP_RATE */ |
145 | if (status->flag & RX_FLAG_HT) { | 145 | if (status->flag & RX_FLAG_HT) { |
146 | /* | 146 | /* |
147 | * TODO: add following information into radiotap header once | 147 | * TODO: add following information into radiotap header once |
148 | * suitable fields are defined for it: | 148 | * suitable fields are defined for it: |
149 | * - MCS index (status->rate_idx) | 149 | * - MCS index (status->rate_idx) |
150 | * - HT40 (status->flag & RX_FLAG_40MHZ) | 150 | * - HT40 (status->flag & RX_FLAG_40MHZ) |
151 | * - short-GI (status->flag & RX_FLAG_SHORT_GI) | 151 | * - short-GI (status->flag & RX_FLAG_SHORT_GI) |
152 | */ | 152 | */ |
153 | *pos = 0; | 153 | *pos = 0; |
154 | } else { | 154 | } else { |
155 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); | 155 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); |
156 | *pos = rate->bitrate / 5; | 156 | *pos = rate->bitrate / 5; |
157 | } | 157 | } |
158 | pos++; | 158 | pos++; |
159 | 159 | ||
160 | /* IEEE80211_RADIOTAP_CHANNEL */ | 160 | /* IEEE80211_RADIOTAP_CHANNEL */ |
161 | put_unaligned_le16(status->freq, pos); | 161 | put_unaligned_le16(status->freq, pos); |
162 | pos += 2; | 162 | pos += 2; |
163 | if (status->band == IEEE80211_BAND_5GHZ) | 163 | if (status->band == IEEE80211_BAND_5GHZ) |
164 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, | 164 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, |
165 | pos); | 165 | pos); |
166 | else if (rate->flags & IEEE80211_RATE_ERP_G) | 166 | else if (rate->flags & IEEE80211_RATE_ERP_G) |
167 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, | 167 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
168 | pos); | 168 | pos); |
169 | else | 169 | else |
170 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, | 170 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, |
171 | pos); | 171 | pos); |
172 | pos += 2; | 172 | pos += 2; |
173 | 173 | ||
174 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | 174 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ |
175 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | 175 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { |
176 | *pos = status->signal; | 176 | *pos = status->signal; |
177 | rthdr->it_present |= | 177 | rthdr->it_present |= |
178 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | 178 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); |
179 | pos++; | 179 | pos++; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ | 182 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ |
183 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | 183 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { |
184 | *pos = status->noise; | 184 | *pos = status->noise; |
185 | rthdr->it_present |= | 185 | rthdr->it_present |= |
186 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); | 186 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); |
187 | pos++; | 187 | pos++; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ | 190 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ |
191 | 191 | ||
192 | /* IEEE80211_RADIOTAP_ANTENNA */ | 192 | /* IEEE80211_RADIOTAP_ANTENNA */ |
193 | *pos = status->antenna; | 193 | *pos = status->antenna; |
194 | pos++; | 194 | pos++; |
195 | 195 | ||
196 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ | 196 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ |
197 | 197 | ||
198 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | 198 | /* IEEE80211_RADIOTAP_RX_FLAGS */ |
199 | /* ensure 2 byte alignment for the 2 byte field as required */ | 199 | /* ensure 2 byte alignment for the 2 byte field as required */ |
200 | if ((pos - (u8 *)rthdr) & 1) | 200 | if ((pos - (u8 *)rthdr) & 1) |
201 | pos++; | 201 | pos++; |
202 | if (status->flag & RX_FLAG_FAILED_PLCP_CRC) | 202 | if (status->flag & RX_FLAG_FAILED_PLCP_CRC) |
203 | rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP; | 203 | rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP; |
204 | put_unaligned_le16(rx_flags, pos); | 204 | put_unaligned_le16(rx_flags, pos); |
205 | pos += 2; | 205 | pos += 2; |
206 | } | 206 | } |
207 | 207 | ||
208 | /* | 208 | /* |
209 | * This function copies a received frame to all monitor interfaces and | 209 | * This function copies a received frame to all monitor interfaces and |
210 | * returns a cleaned-up SKB that no longer includes the FCS nor the | 210 | * returns a cleaned-up SKB that no longer includes the FCS nor the |
211 | * radiotap header the driver might have added. | 211 | * radiotap header the driver might have added. |
212 | */ | 212 | */ |
213 | static struct sk_buff * | 213 | static struct sk_buff * |
214 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | 214 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, |
215 | struct ieee80211_rate *rate) | 215 | struct ieee80211_rate *rate) |
216 | { | 216 | { |
217 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); | 217 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); |
218 | struct ieee80211_sub_if_data *sdata; | 218 | struct ieee80211_sub_if_data *sdata; |
219 | int needed_headroom = 0; | 219 | int needed_headroom = 0; |
220 | struct sk_buff *skb, *skb2; | 220 | struct sk_buff *skb, *skb2; |
221 | struct net_device *prev_dev = NULL; | 221 | struct net_device *prev_dev = NULL; |
222 | int present_fcs_len = 0; | 222 | int present_fcs_len = 0; |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * First, we may need to make a copy of the skb because | 225 | * First, we may need to make a copy of the skb because |
226 | * (1) we need to modify it for radiotap (if not present), and | 226 | * (1) we need to modify it for radiotap (if not present), and |
227 | * (2) the other RX handlers will modify the skb we got. | 227 | * (2) the other RX handlers will modify the skb we got. |
228 | * | 228 | * |
229 | * We don't need to, of course, if we aren't going to return | 229 | * We don't need to, of course, if we aren't going to return |
230 | * the SKB because it has a bad FCS/PLCP checksum. | 230 | * the SKB because it has a bad FCS/PLCP checksum. |
231 | */ | 231 | */ |
232 | 232 | ||
233 | /* room for the radiotap header based on driver features */ | 233 | /* room for the radiotap header based on driver features */ |
234 | needed_headroom = ieee80211_rx_radiotap_len(local, status); | 234 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
235 | 235 | ||
236 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 236 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
237 | present_fcs_len = FCS_LEN; | 237 | present_fcs_len = FCS_LEN; |
238 | 238 | ||
239 | if (!local->monitors) { | 239 | if (!local->monitors) { |
240 | if (should_drop_frame(origskb, present_fcs_len)) { | 240 | if (should_drop_frame(origskb, present_fcs_len)) { |
241 | dev_kfree_skb(origskb); | 241 | dev_kfree_skb(origskb); |
242 | return NULL; | 242 | return NULL; |
243 | } | 243 | } |
244 | 244 | ||
245 | return remove_monitor_info(local, origskb); | 245 | return remove_monitor_info(local, origskb); |
246 | } | 246 | } |
247 | 247 | ||
248 | if (should_drop_frame(origskb, present_fcs_len)) { | 248 | if (should_drop_frame(origskb, present_fcs_len)) { |
249 | /* only need to expand headroom if necessary */ | 249 | /* only need to expand headroom if necessary */ |
250 | skb = origskb; | 250 | skb = origskb; |
251 | origskb = NULL; | 251 | origskb = NULL; |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * This shouldn't trigger often because most devices have an | 254 | * This shouldn't trigger often because most devices have an |
255 | * RX header they pull before we get here, and that should | 255 | * RX header they pull before we get here, and that should |
256 | * be big enough for our radiotap information. We should | 256 | * be big enough for our radiotap information. We should |
257 | * probably export the length to drivers so that we can have | 257 | * probably export the length to drivers so that we can have |
258 | * them allocate enough headroom to start with. | 258 | * them allocate enough headroom to start with. |
259 | */ | 259 | */ |
260 | if (skb_headroom(skb) < needed_headroom && | 260 | if (skb_headroom(skb) < needed_headroom && |
261 | pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) { | 261 | pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) { |
262 | dev_kfree_skb(skb); | 262 | dev_kfree_skb(skb); |
263 | return NULL; | 263 | return NULL; |
264 | } | 264 | } |
265 | } else { | 265 | } else { |
266 | /* | 266 | /* |
267 | * Need to make a copy and possibly remove radiotap header | 267 | * Need to make a copy and possibly remove radiotap header |
268 | * and FCS from the original. | 268 | * and FCS from the original. |
269 | */ | 269 | */ |
270 | skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); | 270 | skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); |
271 | 271 | ||
272 | origskb = remove_monitor_info(local, origskb); | 272 | origskb = remove_monitor_info(local, origskb); |
273 | 273 | ||
274 | if (!skb) | 274 | if (!skb) |
275 | return origskb; | 275 | return origskb; |
276 | } | 276 | } |
277 | 277 | ||
278 | /* prepend radiotap information */ | 278 | /* prepend radiotap information */ |
279 | ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); | 279 | ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); |
280 | 280 | ||
281 | skb_reset_mac_header(skb); | 281 | skb_reset_mac_header(skb); |
282 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 282 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
283 | skb->pkt_type = PACKET_OTHERHOST; | 283 | skb->pkt_type = PACKET_OTHERHOST; |
284 | skb->protocol = htons(ETH_P_802_2); | 284 | skb->protocol = htons(ETH_P_802_2); |
285 | 285 | ||
286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
287 | if (!netif_running(sdata->dev)) | 287 | if (!netif_running(sdata->dev)) |
288 | continue; | 288 | continue; |
289 | 289 | ||
290 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) | 290 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) |
291 | continue; | 291 | continue; |
292 | 292 | ||
293 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) | 293 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) |
294 | continue; | 294 | continue; |
295 | 295 | ||
296 | if (prev_dev) { | 296 | if (prev_dev) { |
297 | skb2 = skb_clone(skb, GFP_ATOMIC); | 297 | skb2 = skb_clone(skb, GFP_ATOMIC); |
298 | if (skb2) { | 298 | if (skb2) { |
299 | skb2->dev = prev_dev; | 299 | skb2->dev = prev_dev; |
300 | netif_rx(skb2); | 300 | netif_rx(skb2); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | prev_dev = sdata->dev; | 304 | prev_dev = sdata->dev; |
305 | sdata->dev->stats.rx_packets++; | 305 | sdata->dev->stats.rx_packets++; |
306 | sdata->dev->stats.rx_bytes += skb->len; | 306 | sdata->dev->stats.rx_bytes += skb->len; |
307 | } | 307 | } |
308 | 308 | ||
309 | if (prev_dev) { | 309 | if (prev_dev) { |
310 | skb->dev = prev_dev; | 310 | skb->dev = prev_dev; |
311 | netif_rx(skb); | 311 | netif_rx(skb); |
312 | } else | 312 | } else |
313 | dev_kfree_skb(skb); | 313 | dev_kfree_skb(skb); |
314 | 314 | ||
315 | return origskb; | 315 | return origskb; |
316 | } | 316 | } |
317 | 317 | ||
318 | 318 | ||
319 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | 319 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) |
320 | { | 320 | { |
321 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 321 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
322 | int tid; | 322 | int tid; |
323 | 323 | ||
324 | /* does the frame have a qos control field? */ | 324 | /* does the frame have a qos control field? */ |
325 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 325 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
326 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 326 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
327 | /* frame has qos control */ | 327 | /* frame has qos control */ |
328 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 328 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
329 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | 329 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) |
330 | rx->flags |= IEEE80211_RX_AMSDU; | 330 | rx->flags |= IEEE80211_RX_AMSDU; |
331 | else | 331 | else |
332 | rx->flags &= ~IEEE80211_RX_AMSDU; | 332 | rx->flags &= ~IEEE80211_RX_AMSDU; |
333 | } else { | 333 | } else { |
334 | /* | 334 | /* |
335 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): | 335 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
336 | * | 336 | * |
337 | * Sequence numbers for management frames, QoS data | 337 | * Sequence numbers for management frames, QoS data |
338 | * frames with a broadcast/multicast address in the | 338 | * frames with a broadcast/multicast address in the |
339 | * Address 1 field, and all non-QoS data frames sent | 339 | * Address 1 field, and all non-QoS data frames sent |
340 | * by QoS STAs are assigned using an additional single | 340 | * by QoS STAs are assigned using an additional single |
341 | * modulo-4096 counter, [...] | 341 | * modulo-4096 counter, [...] |
342 | * | 342 | * |
343 | * We also use that counter for non-QoS STAs. | 343 | * We also use that counter for non-QoS STAs. |
344 | */ | 344 | */ |
345 | tid = NUM_RX_DATA_QUEUES - 1; | 345 | tid = NUM_RX_DATA_QUEUES - 1; |
346 | } | 346 | } |
347 | 347 | ||
348 | rx->queue = tid; | 348 | rx->queue = tid; |
349 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. | 349 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. |
350 | * For now, set skb->priority to 0 for other cases. */ | 350 | * For now, set skb->priority to 0 for other cases. */ |
351 | rx->skb->priority = (tid > 7) ? 0 : tid; | 351 | rx->skb->priority = (tid > 7) ? 0 : tid; |
352 | } | 352 | } |
353 | 353 | ||
354 | /** | 354 | /** |
355 | * DOC: Packet alignment | 355 | * DOC: Packet alignment |
356 | * | 356 | * |
357 | * Drivers always need to pass packets that are aligned to two-byte boundaries | 357 | * Drivers always need to pass packets that are aligned to two-byte boundaries |
358 | * to the stack. | 358 | * to the stack. |
359 | * | 359 | * |
360 | * Additionally, should, if possible, align the payload data in a way that | 360 | * Additionally, should, if possible, align the payload data in a way that |
361 | * guarantees that the contained IP header is aligned to a four-byte | 361 | * guarantees that the contained IP header is aligned to a four-byte |
362 | * boundary. In the case of regular frames, this simply means aligning the | 362 | * boundary. In the case of regular frames, this simply means aligning the |
363 | * payload to a four-byte boundary (because either the IP header is directly | 363 | * payload to a four-byte boundary (because either the IP header is directly |
364 | * contained, or IV/RFC1042 headers that have a length divisible by four are | 364 | * contained, or IV/RFC1042 headers that have a length divisible by four are |
365 | * in front of it). | 365 | * in front of it). |
366 | * | 366 | * |
367 | * With A-MSDU frames, however, the payload data address must yield two modulo | 367 | * With A-MSDU frames, however, the payload data address must yield two modulo |
368 | * four because there are 14-byte 802.3 headers within the A-MSDU frames that | 368 | * four because there are 14-byte 802.3 headers within the A-MSDU frames that |
369 | * push the IP header further back to a multiple of four again. Thankfully, the | 369 | * push the IP header further back to a multiple of four again. Thankfully, the |
370 | * specs were sane enough this time around to require padding each A-MSDU | 370 | * specs were sane enough this time around to require padding each A-MSDU |
371 | * subframe to a length that is a multiple of four. | 371 | * subframe to a length that is a multiple of four. |
372 | * | 372 | * |
373 | * Padding like Atheros hardware adds which is inbetween the 802.11 header and | 373 | * Padding like Atheros hardware adds which is inbetween the 802.11 header and |
374 | * the payload is not supported, the driver is required to move the 802.11 | 374 | * the payload is not supported, the driver is required to move the 802.11 |
375 | * header to be directly in front of the payload in that case. | 375 | * header to be directly in front of the payload in that case. |
376 | */ | 376 | */ |
377 | static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) | 377 | static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) |
378 | { | 378 | { |
379 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 379 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
380 | int hdrlen; | 380 | int hdrlen; |
381 | 381 | ||
382 | #ifndef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT | 382 | #ifndef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT |
383 | return; | 383 | return; |
384 | #endif | 384 | #endif |
385 | 385 | ||
386 | if (WARN_ONCE((unsigned long)rx->skb->data & 1, | 386 | if (WARN_ONCE((unsigned long)rx->skb->data & 1, |
387 | "unaligned packet at 0x%p\n", rx->skb->data)) | 387 | "unaligned packet at 0x%p\n", rx->skb->data)) |
388 | return; | 388 | return; |
389 | 389 | ||
390 | if (!ieee80211_is_data_present(hdr->frame_control)) | 390 | if (!ieee80211_is_data_present(hdr->frame_control)) |
391 | return; | 391 | return; |
392 | 392 | ||
393 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 393 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
394 | if (rx->flags & IEEE80211_RX_AMSDU) | 394 | if (rx->flags & IEEE80211_RX_AMSDU) |
395 | hdrlen += ETH_HLEN; | 395 | hdrlen += ETH_HLEN; |
396 | WARN_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3, | 396 | WARN_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3, |
397 | "unaligned IP payload at 0x%p\n", rx->skb->data + hdrlen); | 397 | "unaligned IP payload at 0x%p\n", rx->skb->data + hdrlen); |
398 | } | 398 | } |
399 | 399 | ||
400 | 400 | ||
401 | /* rx handlers */ | 401 | /* rx handlers */ |
402 | 402 | ||
403 | static ieee80211_rx_result debug_noinline | 403 | static ieee80211_rx_result debug_noinline |
404 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 404 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
405 | { | 405 | { |
406 | struct ieee80211_local *local = rx->local; | 406 | struct ieee80211_local *local = rx->local; |
407 | struct sk_buff *skb = rx->skb; | 407 | struct sk_buff *skb = rx->skb; |
408 | 408 | ||
409 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) | 409 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) |
410 | return ieee80211_scan_rx(rx->sdata, skb); | 410 | return ieee80211_scan_rx(rx->sdata, skb); |
411 | 411 | ||
412 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && | 412 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && |
413 | (rx->flags & IEEE80211_RX_IN_SCAN))) { | 413 | (rx->flags & IEEE80211_RX_IN_SCAN))) { |
414 | /* drop all the other packets during a software scan anyway */ | 414 | /* drop all the other packets during a software scan anyway */ |
415 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) | 415 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) |
416 | dev_kfree_skb(skb); | 416 | dev_kfree_skb(skb); |
417 | return RX_QUEUED; | 417 | return RX_QUEUED; |
418 | } | 418 | } |
419 | 419 | ||
420 | if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { | 420 | if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { |
421 | /* scanning finished during invoking of handlers */ | 421 | /* scanning finished during invoking of handlers */ |
422 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | 422 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); |
423 | return RX_DROP_UNUSABLE; | 423 | return RX_DROP_UNUSABLE; |
424 | } | 424 | } |
425 | 425 | ||
426 | return RX_CONTINUE; | 426 | return RX_CONTINUE; |
427 | } | 427 | } |
428 | 428 | ||
429 | 429 | ||
430 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) | 430 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) |
431 | { | 431 | { |
432 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 432 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
433 | 433 | ||
434 | if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) | 434 | if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) |
435 | return 0; | 435 | return 0; |
436 | 436 | ||
437 | return ieee80211_is_robust_mgmt_frame(hdr); | 437 | return ieee80211_is_robust_mgmt_frame(hdr); |
438 | } | 438 | } |
439 | 439 | ||
440 | 440 | ||
441 | static int ieee80211_is_multicast_robust_mgmt_frame(struct sk_buff *skb) | 441 | static int ieee80211_is_multicast_robust_mgmt_frame(struct sk_buff *skb) |
442 | { | 442 | { |
443 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 443 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
444 | 444 | ||
445 | if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1)) | 445 | if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1)) |
446 | return 0; | 446 | return 0; |
447 | 447 | ||
448 | return ieee80211_is_robust_mgmt_frame(hdr); | 448 | return ieee80211_is_robust_mgmt_frame(hdr); |
449 | } | 449 | } |
450 | 450 | ||
451 | 451 | ||
452 | /* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */ | 452 | /* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */ |
453 | static int ieee80211_get_mmie_keyidx(struct sk_buff *skb) | 453 | static int ieee80211_get_mmie_keyidx(struct sk_buff *skb) |
454 | { | 454 | { |
455 | struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; | 455 | struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; |
456 | struct ieee80211_mmie *mmie; | 456 | struct ieee80211_mmie *mmie; |
457 | 457 | ||
458 | if (skb->len < 24 + sizeof(*mmie) || | 458 | if (skb->len < 24 + sizeof(*mmie) || |
459 | !is_multicast_ether_addr(hdr->da)) | 459 | !is_multicast_ether_addr(hdr->da)) |
460 | return -1; | 460 | return -1; |
461 | 461 | ||
462 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr)) | 462 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr)) |
463 | return -1; /* not a robust management frame */ | 463 | return -1; /* not a robust management frame */ |
464 | 464 | ||
465 | mmie = (struct ieee80211_mmie *) | 465 | mmie = (struct ieee80211_mmie *) |
466 | (skb->data + skb->len - sizeof(*mmie)); | 466 | (skb->data + skb->len - sizeof(*mmie)); |
467 | if (mmie->element_id != WLAN_EID_MMIE || | 467 | if (mmie->element_id != WLAN_EID_MMIE || |
468 | mmie->length != sizeof(*mmie) - 2) | 468 | mmie->length != sizeof(*mmie) - 2) |
469 | return -1; | 469 | return -1; |
470 | 470 | ||
471 | return le16_to_cpu(mmie->key_id); | 471 | return le16_to_cpu(mmie->key_id); |
472 | } | 472 | } |
473 | 473 | ||
474 | 474 | ||
475 | static ieee80211_rx_result | 475 | static ieee80211_rx_result |
476 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | 476 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) |
477 | { | 477 | { |
478 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 478 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
479 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); | 479 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
480 | char *dev_addr = rx->dev->dev_addr; | 480 | char *dev_addr = rx->sdata->dev->dev_addr; |
481 | 481 | ||
482 | if (ieee80211_is_data(hdr->frame_control)) { | 482 | if (ieee80211_is_data(hdr->frame_control)) { |
483 | if (is_multicast_ether_addr(hdr->addr1)) { | 483 | if (is_multicast_ether_addr(hdr->addr1)) { |
484 | if (ieee80211_has_tods(hdr->frame_control) || | 484 | if (ieee80211_has_tods(hdr->frame_control) || |
485 | !ieee80211_has_fromds(hdr->frame_control)) | 485 | !ieee80211_has_fromds(hdr->frame_control)) |
486 | return RX_DROP_MONITOR; | 486 | return RX_DROP_MONITOR; |
487 | if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0) | 487 | if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0) |
488 | return RX_DROP_MONITOR; | 488 | return RX_DROP_MONITOR; |
489 | } else { | 489 | } else { |
490 | if (!ieee80211_has_a4(hdr->frame_control)) | 490 | if (!ieee80211_has_a4(hdr->frame_control)) |
491 | return RX_DROP_MONITOR; | 491 | return RX_DROP_MONITOR; |
492 | if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0) | 492 | if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0) |
493 | return RX_DROP_MONITOR; | 493 | return RX_DROP_MONITOR; |
494 | } | 494 | } |
495 | } | 495 | } |
496 | 496 | ||
497 | /* If there is not an established peer link and this is not a peer link | 497 | /* If there is not an established peer link and this is not a peer link |
498 | * establisment frame, beacon or probe, drop the frame. | 498 | * establisment frame, beacon or probe, drop the frame. |
499 | */ | 499 | */ |
500 | 500 | ||
501 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { | 501 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { |
502 | struct ieee80211_mgmt *mgmt; | 502 | struct ieee80211_mgmt *mgmt; |
503 | 503 | ||
504 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 504 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
505 | return RX_DROP_MONITOR; | 505 | return RX_DROP_MONITOR; |
506 | 506 | ||
507 | if (ieee80211_is_action(hdr->frame_control)) { | 507 | if (ieee80211_is_action(hdr->frame_control)) { |
508 | mgmt = (struct ieee80211_mgmt *)hdr; | 508 | mgmt = (struct ieee80211_mgmt *)hdr; |
509 | if (mgmt->u.action.category != MESH_PLINK_CATEGORY) | 509 | if (mgmt->u.action.category != MESH_PLINK_CATEGORY) |
510 | return RX_DROP_MONITOR; | 510 | return RX_DROP_MONITOR; |
511 | return RX_CONTINUE; | 511 | return RX_CONTINUE; |
512 | } | 512 | } |
513 | 513 | ||
514 | if (ieee80211_is_probe_req(hdr->frame_control) || | 514 | if (ieee80211_is_probe_req(hdr->frame_control) || |
515 | ieee80211_is_probe_resp(hdr->frame_control) || | 515 | ieee80211_is_probe_resp(hdr->frame_control) || |
516 | ieee80211_is_beacon(hdr->frame_control)) | 516 | ieee80211_is_beacon(hdr->frame_control)) |
517 | return RX_CONTINUE; | 517 | return RX_CONTINUE; |
518 | 518 | ||
519 | return RX_DROP_MONITOR; | 519 | return RX_DROP_MONITOR; |
520 | 520 | ||
521 | } | 521 | } |
522 | 522 | ||
523 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) | 523 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) |
524 | 524 | ||
525 | if (ieee80211_is_data(hdr->frame_control) && | 525 | if (ieee80211_is_data(hdr->frame_control) && |
526 | is_multicast_ether_addr(hdr->addr1) && | 526 | is_multicast_ether_addr(hdr->addr1) && |
527 | mesh_rmc_check(hdr->addr3, msh_h_get(hdr, hdrlen), rx->sdata)) | 527 | mesh_rmc_check(hdr->addr3, msh_h_get(hdr, hdrlen), rx->sdata)) |
528 | return RX_DROP_MONITOR; | 528 | return RX_DROP_MONITOR; |
529 | #undef msh_h_get | 529 | #undef msh_h_get |
530 | 530 | ||
531 | return RX_CONTINUE; | 531 | return RX_CONTINUE; |
532 | } | 532 | } |
533 | 533 | ||
534 | 534 | ||
535 | static ieee80211_rx_result debug_noinline | 535 | static ieee80211_rx_result debug_noinline |
536 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 536 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
537 | { | 537 | { |
538 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 538 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
539 | 539 | ||
540 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 540 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
541 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 541 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
542 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 542 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
543 | rx->sta->last_seq_ctrl[rx->queue] == | 543 | rx->sta->last_seq_ctrl[rx->queue] == |
544 | hdr->seq_ctrl)) { | 544 | hdr->seq_ctrl)) { |
545 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 545 | if (rx->flags & IEEE80211_RX_RA_MATCH) { |
546 | rx->local->dot11FrameDuplicateCount++; | 546 | rx->local->dot11FrameDuplicateCount++; |
547 | rx->sta->num_duplicates++; | 547 | rx->sta->num_duplicates++; |
548 | } | 548 | } |
549 | return RX_DROP_MONITOR; | 549 | return RX_DROP_MONITOR; |
550 | } else | 550 | } else |
551 | rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl; | 551 | rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl; |
552 | } | 552 | } |
553 | 553 | ||
554 | if (unlikely(rx->skb->len < 16)) { | 554 | if (unlikely(rx->skb->len < 16)) { |
555 | I802_DEBUG_INC(rx->local->rx_handlers_drop_short); | 555 | I802_DEBUG_INC(rx->local->rx_handlers_drop_short); |
556 | return RX_DROP_MONITOR; | 556 | return RX_DROP_MONITOR; |
557 | } | 557 | } |
558 | 558 | ||
559 | /* Drop disallowed frame classes based on STA auth/assoc state; | 559 | /* Drop disallowed frame classes based on STA auth/assoc state; |
560 | * IEEE 802.11, Chap 5.5. | 560 | * IEEE 802.11, Chap 5.5. |
561 | * | 561 | * |
562 | * mac80211 filters only based on association state, i.e. it drops | 562 | * mac80211 filters only based on association state, i.e. it drops |
563 | * Class 3 frames from not associated stations. hostapd sends | 563 | * Class 3 frames from not associated stations. hostapd sends |
564 | * deauth/disassoc frames when needed. In addition, hostapd is | 564 | * deauth/disassoc frames when needed. In addition, hostapd is |
565 | * responsible for filtering on both auth and assoc states. | 565 | * responsible for filtering on both auth and assoc states. |
566 | */ | 566 | */ |
567 | 567 | ||
568 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) | 568 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
569 | return ieee80211_rx_mesh_check(rx); | 569 | return ieee80211_rx_mesh_check(rx); |
570 | 570 | ||
571 | if (unlikely((ieee80211_is_data(hdr->frame_control) || | 571 | if (unlikely((ieee80211_is_data(hdr->frame_control) || |
572 | ieee80211_is_pspoll(hdr->frame_control)) && | 572 | ieee80211_is_pspoll(hdr->frame_control)) && |
573 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 573 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
574 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 574 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
575 | if ((!ieee80211_has_fromds(hdr->frame_control) && | 575 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
576 | !ieee80211_has_tods(hdr->frame_control) && | 576 | !ieee80211_has_tods(hdr->frame_control) && |
577 | ieee80211_is_data(hdr->frame_control)) || | 577 | ieee80211_is_data(hdr->frame_control)) || |
578 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 578 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { |
579 | /* Drop IBSS frames and frames for other hosts | 579 | /* Drop IBSS frames and frames for other hosts |
580 | * silently. */ | 580 | * silently. */ |
581 | return RX_DROP_MONITOR; | 581 | return RX_DROP_MONITOR; |
582 | } | 582 | } |
583 | 583 | ||
584 | return RX_DROP_MONITOR; | 584 | return RX_DROP_MONITOR; |
585 | } | 585 | } |
586 | 586 | ||
587 | return RX_CONTINUE; | 587 | return RX_CONTINUE; |
588 | } | 588 | } |
589 | 589 | ||
590 | 590 | ||
591 | static ieee80211_rx_result debug_noinline | 591 | static ieee80211_rx_result debug_noinline |
592 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 592 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
593 | { | 593 | { |
594 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 594 | struct sk_buff *skb = rx->skb; |
595 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
596 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
595 | int keyidx; | 597 | int keyidx; |
596 | int hdrlen; | 598 | int hdrlen; |
597 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 599 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
598 | struct ieee80211_key *stakey = NULL; | 600 | struct ieee80211_key *stakey = NULL; |
599 | int mmie_keyidx = -1; | 601 | int mmie_keyidx = -1; |
600 | 602 | ||
601 | /* | 603 | /* |
602 | * Key selection 101 | 604 | * Key selection 101 |
603 | * | 605 | * |
604 | * There are four types of keys: | 606 | * There are four types of keys: |
605 | * - GTK (group keys) | 607 | * - GTK (group keys) |
606 | * - IGTK (group keys for management frames) | 608 | * - IGTK (group keys for management frames) |
607 | * - PTK (pairwise keys) | 609 | * - PTK (pairwise keys) |
608 | * - STK (station-to-station pairwise keys) | 610 | * - STK (station-to-station pairwise keys) |
609 | * | 611 | * |
610 | * When selecting a key, we have to distinguish between multicast | 612 | * When selecting a key, we have to distinguish between multicast |
611 | * (including broadcast) and unicast frames, the latter can only | 613 | * (including broadcast) and unicast frames, the latter can only |
612 | * use PTKs and STKs while the former always use GTKs and IGTKs. | 614 | * use PTKs and STKs while the former always use GTKs and IGTKs. |
613 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then | 615 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then |
614 | * unicast frames can also use key indices like GTKs. Hence, if we | 616 | * unicast frames can also use key indices like GTKs. Hence, if we |
615 | * don't have a PTK/STK we check the key index for a WEP key. | 617 | * don't have a PTK/STK we check the key index for a WEP key. |
616 | * | 618 | * |
617 | * Note that in a regular BSS, multicast frames are sent by the | 619 | * Note that in a regular BSS, multicast frames are sent by the |
618 | * AP only, associated stations unicast the frame to the AP first | 620 | * AP only, associated stations unicast the frame to the AP first |
619 | * which then multicasts it on their behalf. | 621 | * which then multicasts it on their behalf. |
620 | * | 622 | * |
621 | * There is also a slight problem in IBSS mode: GTKs are negotiated | 623 | * There is also a slight problem in IBSS mode: GTKs are negotiated |
622 | * with each station, that is something we don't currently handle. | 624 | * with each station, that is something we don't currently handle. |
623 | * The spec seems to expect that one negotiates the same key with | 625 | * The spec seems to expect that one negotiates the same key with |
624 | * every station but there's no such requirement; VLANs could be | 626 | * every station but there's no such requirement; VLANs could be |
625 | * possible. | 627 | * possible. |
626 | */ | 628 | */ |
627 | 629 | ||
628 | /* | 630 | /* |
629 | * No point in finding a key and decrypting if the frame is neither | 631 | * No point in finding a key and decrypting if the frame is neither |
630 | * addressed to us nor a multicast frame. | 632 | * addressed to us nor a multicast frame. |
631 | */ | 633 | */ |
632 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 634 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
633 | return RX_CONTINUE; | 635 | return RX_CONTINUE; |
634 | 636 | ||
635 | if (rx->sta) | 637 | if (rx->sta) |
636 | stakey = rcu_dereference(rx->sta->key); | 638 | stakey = rcu_dereference(rx->sta->key); |
637 | 639 | ||
638 | if (!ieee80211_has_protected(hdr->frame_control)) | 640 | if (!ieee80211_has_protected(hdr->frame_control)) |
639 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | 641 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); |
640 | 642 | ||
641 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 643 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { |
642 | rx->key = stakey; | 644 | rx->key = stakey; |
643 | /* Skip decryption if the frame is not protected. */ | 645 | /* Skip decryption if the frame is not protected. */ |
644 | if (!ieee80211_has_protected(hdr->frame_control)) | 646 | if (!ieee80211_has_protected(hdr->frame_control)) |
645 | return RX_CONTINUE; | 647 | return RX_CONTINUE; |
646 | } else if (mmie_keyidx >= 0) { | 648 | } else if (mmie_keyidx >= 0) { |
647 | /* Broadcast/multicast robust management frame / BIP */ | 649 | /* Broadcast/multicast robust management frame / BIP */ |
648 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 650 | if ((status->flag & RX_FLAG_DECRYPTED) && |
649 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 651 | (status->flag & RX_FLAG_IV_STRIPPED)) |
650 | return RX_CONTINUE; | 652 | return RX_CONTINUE; |
651 | 653 | ||
652 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | 654 | if (mmie_keyidx < NUM_DEFAULT_KEYS || |
653 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | 655 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) |
654 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | 656 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ |
655 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | 657 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); |
656 | } else if (!ieee80211_has_protected(hdr->frame_control)) { | 658 | } else if (!ieee80211_has_protected(hdr->frame_control)) { |
657 | /* | 659 | /* |
658 | * The frame was not protected, so skip decryption. However, we | 660 | * The frame was not protected, so skip decryption. However, we |
659 | * need to set rx->key if there is a key that could have been | 661 | * need to set rx->key if there is a key that could have been |
660 | * used so that the frame may be dropped if encryption would | 662 | * used so that the frame may be dropped if encryption would |
661 | * have been expected. | 663 | * have been expected. |
662 | */ | 664 | */ |
663 | struct ieee80211_key *key = NULL; | 665 | struct ieee80211_key *key = NULL; |
664 | if (ieee80211_is_mgmt(hdr->frame_control) && | 666 | if (ieee80211_is_mgmt(hdr->frame_control) && |
665 | is_multicast_ether_addr(hdr->addr1) && | 667 | is_multicast_ether_addr(hdr->addr1) && |
666 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | 668 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) |
667 | rx->key = key; | 669 | rx->key = key; |
668 | else if ((key = rcu_dereference(rx->sdata->default_key))) | 670 | else if ((key = rcu_dereference(rx->sdata->default_key))) |
669 | rx->key = key; | 671 | rx->key = key; |
670 | return RX_CONTINUE; | 672 | return RX_CONTINUE; |
671 | } else { | 673 | } else { |
672 | /* | 674 | /* |
673 | * The device doesn't give us the IV so we won't be | 675 | * The device doesn't give us the IV so we won't be |
674 | * able to look up the key. That's ok though, we | 676 | * able to look up the key. That's ok though, we |
675 | * don't need to decrypt the frame, we just won't | 677 | * don't need to decrypt the frame, we just won't |
676 | * be able to keep statistics accurate. | 678 | * be able to keep statistics accurate. |
677 | * Except for key threshold notifications, should | 679 | * Except for key threshold notifications, should |
678 | * we somehow allow the driver to tell us which key | 680 | * we somehow allow the driver to tell us which key |
679 | * the hardware used if this flag is set? | 681 | * the hardware used if this flag is set? |
680 | */ | 682 | */ |
681 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 683 | if ((status->flag & RX_FLAG_DECRYPTED) && |
682 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 684 | (status->flag & RX_FLAG_IV_STRIPPED)) |
683 | return RX_CONTINUE; | 685 | return RX_CONTINUE; |
684 | 686 | ||
685 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 687 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
686 | 688 | ||
687 | if (rx->skb->len < 8 + hdrlen) | 689 | if (rx->skb->len < 8 + hdrlen) |
688 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | 690 | return RX_DROP_UNUSABLE; /* TODO: count this? */ |
689 | 691 | ||
690 | /* | 692 | /* |
691 | * no need to call ieee80211_wep_get_keyidx, | 693 | * no need to call ieee80211_wep_get_keyidx, |
692 | * it verifies a bunch of things we've done already | 694 | * it verifies a bunch of things we've done already |
693 | */ | 695 | */ |
694 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | 696 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
695 | 697 | ||
696 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | 698 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); |
697 | 699 | ||
698 | /* | 700 | /* |
699 | * RSNA-protected unicast frames should always be sent with | 701 | * RSNA-protected unicast frames should always be sent with |
700 | * pairwise or station-to-station keys, but for WEP we allow | 702 | * pairwise or station-to-station keys, but for WEP we allow |
701 | * using a key index as well. | 703 | * using a key index as well. |
702 | */ | 704 | */ |
703 | if (rx->key && rx->key->conf.alg != ALG_WEP && | 705 | if (rx->key && rx->key->conf.alg != ALG_WEP && |
704 | !is_multicast_ether_addr(hdr->addr1)) | 706 | !is_multicast_ether_addr(hdr->addr1)) |
705 | rx->key = NULL; | 707 | rx->key = NULL; |
706 | } | 708 | } |
707 | 709 | ||
708 | if (rx->key) { | 710 | if (rx->key) { |
709 | rx->key->tx_rx_count++; | 711 | rx->key->tx_rx_count++; |
710 | /* TODO: add threshold stuff again */ | 712 | /* TODO: add threshold stuff again */ |
711 | } else { | 713 | } else { |
712 | return RX_DROP_MONITOR; | 714 | return RX_DROP_MONITOR; |
713 | } | 715 | } |
714 | 716 | ||
715 | /* Check for weak IVs if possible */ | 717 | /* Check for weak IVs if possible */ |
716 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | 718 | if (rx->sta && rx->key->conf.alg == ALG_WEP && |
717 | ieee80211_is_data(hdr->frame_control) && | 719 | ieee80211_is_data(hdr->frame_control) && |
718 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || | 720 | (!(status->flag & RX_FLAG_IV_STRIPPED) || |
719 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && | 721 | !(status->flag & RX_FLAG_DECRYPTED)) && |
720 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 722 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
721 | rx->sta->wep_weak_iv_count++; | 723 | rx->sta->wep_weak_iv_count++; |
722 | 724 | ||
723 | switch (rx->key->conf.alg) { | 725 | switch (rx->key->conf.alg) { |
724 | case ALG_WEP: | 726 | case ALG_WEP: |
725 | result = ieee80211_crypto_wep_decrypt(rx); | 727 | result = ieee80211_crypto_wep_decrypt(rx); |
726 | break; | 728 | break; |
727 | case ALG_TKIP: | 729 | case ALG_TKIP: |
728 | result = ieee80211_crypto_tkip_decrypt(rx); | 730 | result = ieee80211_crypto_tkip_decrypt(rx); |
729 | break; | 731 | break; |
730 | case ALG_CCMP: | 732 | case ALG_CCMP: |
731 | result = ieee80211_crypto_ccmp_decrypt(rx); | 733 | result = ieee80211_crypto_ccmp_decrypt(rx); |
732 | break; | 734 | break; |
733 | case ALG_AES_CMAC: | 735 | case ALG_AES_CMAC: |
734 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | 736 | result = ieee80211_crypto_aes_cmac_decrypt(rx); |
735 | break; | 737 | break; |
736 | } | 738 | } |
737 | 739 | ||
738 | /* either the frame has been decrypted or will be dropped */ | 740 | /* either the frame has been decrypted or will be dropped */ |
739 | rx->status->flag |= RX_FLAG_DECRYPTED; | 741 | status->flag |= RX_FLAG_DECRYPTED; |
740 | 742 | ||
741 | return result; | 743 | return result; |
742 | } | 744 | } |
743 | 745 | ||
744 | static ieee80211_rx_result debug_noinline | 746 | static ieee80211_rx_result debug_noinline |
745 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) | 747 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) |
746 | { | 748 | { |
747 | struct ieee80211_local *local; | 749 | struct ieee80211_local *local; |
748 | struct ieee80211_hdr *hdr; | 750 | struct ieee80211_hdr *hdr; |
749 | struct sk_buff *skb; | 751 | struct sk_buff *skb; |
750 | 752 | ||
751 | local = rx->local; | 753 | local = rx->local; |
752 | skb = rx->skb; | 754 | skb = rx->skb; |
753 | hdr = (struct ieee80211_hdr *) skb->data; | 755 | hdr = (struct ieee80211_hdr *) skb->data; |
754 | 756 | ||
755 | if (!local->pspolling) | 757 | if (!local->pspolling) |
756 | return RX_CONTINUE; | 758 | return RX_CONTINUE; |
757 | 759 | ||
758 | if (!ieee80211_has_fromds(hdr->frame_control)) | 760 | if (!ieee80211_has_fromds(hdr->frame_control)) |
759 | /* this is not from AP */ | 761 | /* this is not from AP */ |
760 | return RX_CONTINUE; | 762 | return RX_CONTINUE; |
761 | 763 | ||
762 | if (!ieee80211_is_data(hdr->frame_control)) | 764 | if (!ieee80211_is_data(hdr->frame_control)) |
763 | return RX_CONTINUE; | 765 | return RX_CONTINUE; |
764 | 766 | ||
765 | if (!ieee80211_has_moredata(hdr->frame_control)) { | 767 | if (!ieee80211_has_moredata(hdr->frame_control)) { |
766 | /* AP has no more frames buffered for us */ | 768 | /* AP has no more frames buffered for us */ |
767 | local->pspolling = false; | 769 | local->pspolling = false; |
768 | return RX_CONTINUE; | 770 | return RX_CONTINUE; |
769 | } | 771 | } |
770 | 772 | ||
771 | /* more data bit is set, let's request a new frame from the AP */ | 773 | /* more data bit is set, let's request a new frame from the AP */ |
772 | ieee80211_send_pspoll(local, rx->sdata); | 774 | ieee80211_send_pspoll(local, rx->sdata); |
773 | 775 | ||
774 | return RX_CONTINUE; | 776 | return RX_CONTINUE; |
775 | } | 777 | } |
776 | 778 | ||
777 | static void ap_sta_ps_start(struct sta_info *sta) | 779 | static void ap_sta_ps_start(struct sta_info *sta) |
778 | { | 780 | { |
779 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 781 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
780 | struct ieee80211_local *local = sdata->local; | 782 | struct ieee80211_local *local = sdata->local; |
781 | 783 | ||
782 | atomic_inc(&sdata->bss->num_sta_ps); | 784 | atomic_inc(&sdata->bss->num_sta_ps); |
783 | set_sta_flags(sta, WLAN_STA_PS_STA); | 785 | set_sta_flags(sta, WLAN_STA_PS_STA); |
784 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); | 786 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); |
785 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 787 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
786 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 788 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
787 | sdata->dev->name, sta->sta.addr, sta->sta.aid); | 789 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
788 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 790 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
789 | } | 791 | } |
790 | 792 | ||
791 | static void ap_sta_ps_end(struct sta_info *sta) | 793 | static void ap_sta_ps_end(struct sta_info *sta) |
792 | { | 794 | { |
793 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 795 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
794 | 796 | ||
795 | atomic_dec(&sdata->bss->num_sta_ps); | 797 | atomic_dec(&sdata->bss->num_sta_ps); |
796 | 798 | ||
797 | clear_sta_flags(sta, WLAN_STA_PS_STA); | 799 | clear_sta_flags(sta, WLAN_STA_PS_STA); |
798 | 800 | ||
799 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 801 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
800 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 802 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", |
801 | sdata->dev->name, sta->sta.addr, sta->sta.aid); | 803 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
802 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 804 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
803 | 805 | ||
804 | if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { | 806 | if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { |
805 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 807 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
806 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 808 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", |
807 | sdata->dev->name, sta->sta.addr, sta->sta.aid); | 809 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
808 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 810 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
809 | return; | 811 | return; |
810 | } | 812 | } |
811 | 813 | ||
812 | ieee80211_sta_ps_deliver_wakeup(sta); | 814 | ieee80211_sta_ps_deliver_wakeup(sta); |
813 | } | 815 | } |
814 | 816 | ||
815 | static ieee80211_rx_result debug_noinline | 817 | static ieee80211_rx_result debug_noinline |
816 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 818 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
817 | { | 819 | { |
818 | struct sta_info *sta = rx->sta; | 820 | struct sta_info *sta = rx->sta; |
819 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 821 | struct sk_buff *skb = rx->skb; |
822 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
820 | 824 | ||
821 | if (!sta) | 825 | if (!sta) |
822 | return RX_CONTINUE; | 826 | return RX_CONTINUE; |
823 | 827 | ||
824 | /* | 828 | /* |
825 | * Update last_rx only for IBSS packets which are for the current | 829 | * Update last_rx only for IBSS packets which are for the current |
826 | * BSSID to avoid keeping the current IBSS network alive in cases | 830 | * BSSID to avoid keeping the current IBSS network alive in cases |
827 | * where other STAs start using different BSSID. | 831 | * where other STAs start using different BSSID. |
828 | */ | 832 | */ |
829 | if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 833 | if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
830 | u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, | 834 | u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, |
831 | NL80211_IFTYPE_ADHOC); | 835 | NL80211_IFTYPE_ADHOC); |
832 | if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) | 836 | if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) |
833 | sta->last_rx = jiffies; | 837 | sta->last_rx = jiffies; |
834 | } else if (!is_multicast_ether_addr(hdr->addr1)) { | 838 | } else if (!is_multicast_ether_addr(hdr->addr1)) { |
835 | /* | 839 | /* |
836 | * Mesh beacons will update last_rx when if they are found to | 840 | * Mesh beacons will update last_rx when if they are found to |
837 | * match the current local configuration when processed. | 841 | * match the current local configuration when processed. |
838 | */ | 842 | */ |
839 | sta->last_rx = jiffies; | 843 | sta->last_rx = jiffies; |
840 | } | 844 | } |
841 | 845 | ||
842 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 846 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
843 | return RX_CONTINUE; | 847 | return RX_CONTINUE; |
844 | 848 | ||
845 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) | 849 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) |
846 | ieee80211_sta_rx_notify(rx->sdata, hdr); | 850 | ieee80211_sta_rx_notify(rx->sdata, hdr); |
847 | 851 | ||
848 | sta->rx_fragments++; | 852 | sta->rx_fragments++; |
849 | sta->rx_bytes += rx->skb->len; | 853 | sta->rx_bytes += rx->skb->len; |
850 | sta->last_signal = rx->status->signal; | 854 | sta->last_signal = status->signal; |
851 | sta->last_noise = rx->status->noise; | 855 | sta->last_noise = status->noise; |
852 | 856 | ||
853 | /* | 857 | /* |
854 | * Change STA power saving mode only at the end of a frame | 858 | * Change STA power saving mode only at the end of a frame |
855 | * exchange sequence. | 859 | * exchange sequence. |
856 | */ | 860 | */ |
857 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 861 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
858 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 862 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
859 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 863 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
860 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { | 864 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { |
861 | /* | 865 | /* |
862 | * Ignore doze->wake transitions that are | 866 | * Ignore doze->wake transitions that are |
863 | * indicated by non-data frames, the standard | 867 | * indicated by non-data frames, the standard |
864 | * is unclear here, but for example going to | 868 | * is unclear here, but for example going to |
865 | * PS mode and then scanning would cause a | 869 | * PS mode and then scanning would cause a |
866 | * doze->wake transition for the probe request, | 870 | * doze->wake transition for the probe request, |
867 | * and that is clearly undesirable. | 871 | * and that is clearly undesirable. |
868 | */ | 872 | */ |
869 | if (ieee80211_is_data(hdr->frame_control) && | 873 | if (ieee80211_is_data(hdr->frame_control) && |
870 | !ieee80211_has_pm(hdr->frame_control)) | 874 | !ieee80211_has_pm(hdr->frame_control)) |
871 | ap_sta_ps_end(sta); | 875 | ap_sta_ps_end(sta); |
872 | } else { | 876 | } else { |
873 | if (ieee80211_has_pm(hdr->frame_control)) | 877 | if (ieee80211_has_pm(hdr->frame_control)) |
874 | ap_sta_ps_start(sta); | 878 | ap_sta_ps_start(sta); |
875 | } | 879 | } |
876 | } | 880 | } |
877 | 881 | ||
878 | /* | 882 | /* |
879 | * Drop (qos-)data::nullfunc frames silently, since they | 883 | * Drop (qos-)data::nullfunc frames silently, since they |
880 | * are used only to control station power saving mode. | 884 | * are used only to control station power saving mode. |
881 | */ | 885 | */ |
882 | if (ieee80211_is_nullfunc(hdr->frame_control) || | 886 | if (ieee80211_is_nullfunc(hdr->frame_control) || |
883 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { | 887 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { |
884 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); | 888 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); |
885 | /* | 889 | /* |
886 | * Update counter and free packet here to avoid | 890 | * Update counter and free packet here to avoid |
887 | * counting this as a dropped packed. | 891 | * counting this as a dropped packed. |
888 | */ | 892 | */ |
889 | sta->rx_packets++; | 893 | sta->rx_packets++; |
890 | dev_kfree_skb(rx->skb); | 894 | dev_kfree_skb(rx->skb); |
891 | return RX_QUEUED; | 895 | return RX_QUEUED; |
892 | } | 896 | } |
893 | 897 | ||
894 | return RX_CONTINUE; | 898 | return RX_CONTINUE; |
895 | } /* ieee80211_rx_h_sta_process */ | 899 | } /* ieee80211_rx_h_sta_process */ |
896 | 900 | ||
897 | static inline struct ieee80211_fragment_entry * | 901 | static inline struct ieee80211_fragment_entry * |
898 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | 902 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, |
899 | unsigned int frag, unsigned int seq, int rx_queue, | 903 | unsigned int frag, unsigned int seq, int rx_queue, |
900 | struct sk_buff **skb) | 904 | struct sk_buff **skb) |
901 | { | 905 | { |
902 | struct ieee80211_fragment_entry *entry; | 906 | struct ieee80211_fragment_entry *entry; |
903 | int idx; | 907 | int idx; |
904 | 908 | ||
905 | idx = sdata->fragment_next; | 909 | idx = sdata->fragment_next; |
906 | entry = &sdata->fragments[sdata->fragment_next++]; | 910 | entry = &sdata->fragments[sdata->fragment_next++]; |
907 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) | 911 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |
908 | sdata->fragment_next = 0; | 912 | sdata->fragment_next = 0; |
909 | 913 | ||
910 | if (!skb_queue_empty(&entry->skb_list)) { | 914 | if (!skb_queue_empty(&entry->skb_list)) { |
911 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 915 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
912 | struct ieee80211_hdr *hdr = | 916 | struct ieee80211_hdr *hdr = |
913 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 917 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
914 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | 918 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " |
915 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | 919 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " |
916 | "addr1=%pM addr2=%pM\n", | 920 | "addr1=%pM addr2=%pM\n", |
917 | sdata->dev->name, idx, | 921 | sdata->dev->name, idx, |
918 | jiffies - entry->first_frag_time, entry->seq, | 922 | jiffies - entry->first_frag_time, entry->seq, |
919 | entry->last_frag, hdr->addr1, hdr->addr2); | 923 | entry->last_frag, hdr->addr1, hdr->addr2); |
920 | #endif | 924 | #endif |
921 | __skb_queue_purge(&entry->skb_list); | 925 | __skb_queue_purge(&entry->skb_list); |
922 | } | 926 | } |
923 | 927 | ||
924 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ | 928 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ |
925 | *skb = NULL; | 929 | *skb = NULL; |
926 | entry->first_frag_time = jiffies; | 930 | entry->first_frag_time = jiffies; |
927 | entry->seq = seq; | 931 | entry->seq = seq; |
928 | entry->rx_queue = rx_queue; | 932 | entry->rx_queue = rx_queue; |
929 | entry->last_frag = frag; | 933 | entry->last_frag = frag; |
930 | entry->ccmp = 0; | 934 | entry->ccmp = 0; |
931 | entry->extra_len = 0; | 935 | entry->extra_len = 0; |
932 | 936 | ||
933 | return entry; | 937 | return entry; |
934 | } | 938 | } |
935 | 939 | ||
936 | static inline struct ieee80211_fragment_entry * | 940 | static inline struct ieee80211_fragment_entry * |
937 | ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | 941 | ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, |
938 | unsigned int frag, unsigned int seq, | 942 | unsigned int frag, unsigned int seq, |
939 | int rx_queue, struct ieee80211_hdr *hdr) | 943 | int rx_queue, struct ieee80211_hdr *hdr) |
940 | { | 944 | { |
941 | struct ieee80211_fragment_entry *entry; | 945 | struct ieee80211_fragment_entry *entry; |
942 | int i, idx; | 946 | int i, idx; |
943 | 947 | ||
944 | idx = sdata->fragment_next; | 948 | idx = sdata->fragment_next; |
945 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { | 949 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { |
946 | struct ieee80211_hdr *f_hdr; | 950 | struct ieee80211_hdr *f_hdr; |
947 | 951 | ||
948 | idx--; | 952 | idx--; |
949 | if (idx < 0) | 953 | if (idx < 0) |
950 | idx = IEEE80211_FRAGMENT_MAX - 1; | 954 | idx = IEEE80211_FRAGMENT_MAX - 1; |
951 | 955 | ||
952 | entry = &sdata->fragments[idx]; | 956 | entry = &sdata->fragments[idx]; |
953 | if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || | 957 | if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || |
954 | entry->rx_queue != rx_queue || | 958 | entry->rx_queue != rx_queue || |
955 | entry->last_frag + 1 != frag) | 959 | entry->last_frag + 1 != frag) |
956 | continue; | 960 | continue; |
957 | 961 | ||
958 | f_hdr = (struct ieee80211_hdr *)entry->skb_list.next->data; | 962 | f_hdr = (struct ieee80211_hdr *)entry->skb_list.next->data; |
959 | 963 | ||
960 | /* | 964 | /* |
961 | * Check ftype and addresses are equal, else check next fragment | 965 | * Check ftype and addresses are equal, else check next fragment |
962 | */ | 966 | */ |
963 | if (((hdr->frame_control ^ f_hdr->frame_control) & | 967 | if (((hdr->frame_control ^ f_hdr->frame_control) & |
964 | cpu_to_le16(IEEE80211_FCTL_FTYPE)) || | 968 | cpu_to_le16(IEEE80211_FCTL_FTYPE)) || |
965 | compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || | 969 | compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || |
966 | compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) | 970 | compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) |
967 | continue; | 971 | continue; |
968 | 972 | ||
969 | if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { | 973 | if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { |
970 | __skb_queue_purge(&entry->skb_list); | 974 | __skb_queue_purge(&entry->skb_list); |
971 | continue; | 975 | continue; |
972 | } | 976 | } |
973 | return entry; | 977 | return entry; |
974 | } | 978 | } |
975 | 979 | ||
976 | return NULL; | 980 | return NULL; |
977 | } | 981 | } |
978 | 982 | ||
979 | static ieee80211_rx_result debug_noinline | 983 | static ieee80211_rx_result debug_noinline |
980 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | 984 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |
981 | { | 985 | { |
982 | struct ieee80211_hdr *hdr; | 986 | struct ieee80211_hdr *hdr; |
983 | u16 sc; | 987 | u16 sc; |
984 | __le16 fc; | 988 | __le16 fc; |
985 | unsigned int frag, seq; | 989 | unsigned int frag, seq; |
986 | struct ieee80211_fragment_entry *entry; | 990 | struct ieee80211_fragment_entry *entry; |
987 | struct sk_buff *skb; | 991 | struct sk_buff *skb; |
988 | 992 | ||
989 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 993 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
990 | fc = hdr->frame_control; | 994 | fc = hdr->frame_control; |
991 | sc = le16_to_cpu(hdr->seq_ctrl); | 995 | sc = le16_to_cpu(hdr->seq_ctrl); |
992 | frag = sc & IEEE80211_SCTL_FRAG; | 996 | frag = sc & IEEE80211_SCTL_FRAG; |
993 | 997 | ||
994 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || | 998 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || |
995 | (rx->skb)->len < 24 || | 999 | (rx->skb)->len < 24 || |
996 | is_multicast_ether_addr(hdr->addr1))) { | 1000 | is_multicast_ether_addr(hdr->addr1))) { |
997 | /* not fragmented */ | 1001 | /* not fragmented */ |
998 | goto out; | 1002 | goto out; |
999 | } | 1003 | } |
1000 | I802_DEBUG_INC(rx->local->rx_handlers_fragments); | 1004 | I802_DEBUG_INC(rx->local->rx_handlers_fragments); |
1001 | 1005 | ||
1002 | seq = (sc & IEEE80211_SCTL_SEQ) >> 4; | 1006 | seq = (sc & IEEE80211_SCTL_SEQ) >> 4; |
1003 | 1007 | ||
1004 | if (frag == 0) { | 1008 | if (frag == 0) { |
1005 | /* This is the first fragment of a new frame. */ | 1009 | /* This is the first fragment of a new frame. */ |
1006 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, | 1010 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |
1007 | rx->queue, &(rx->skb)); | 1011 | rx->queue, &(rx->skb)); |
1008 | if (rx->key && rx->key->conf.alg == ALG_CCMP && | 1012 | if (rx->key && rx->key->conf.alg == ALG_CCMP && |
1009 | ieee80211_has_protected(fc)) { | 1013 | ieee80211_has_protected(fc)) { |
1010 | /* Store CCMP PN so that we can verify that the next | 1014 | /* Store CCMP PN so that we can verify that the next |
1011 | * fragment has a sequential PN value. */ | 1015 | * fragment has a sequential PN value. */ |
1012 | entry->ccmp = 1; | 1016 | entry->ccmp = 1; |
1013 | memcpy(entry->last_pn, | 1017 | memcpy(entry->last_pn, |
1014 | rx->key->u.ccmp.rx_pn[rx->queue], | 1018 | rx->key->u.ccmp.rx_pn[rx->queue], |
1015 | CCMP_PN_LEN); | 1019 | CCMP_PN_LEN); |
1016 | } | 1020 | } |
1017 | return RX_QUEUED; | 1021 | return RX_QUEUED; |
1018 | } | 1022 | } |
1019 | 1023 | ||
1020 | /* This is a fragment for a frame that should already be pending in | 1024 | /* This is a fragment for a frame that should already be pending in |
1021 | * fragment cache. Add this fragment to the end of the pending entry. | 1025 | * fragment cache. Add this fragment to the end of the pending entry. |
1022 | */ | 1026 | */ |
1023 | entry = ieee80211_reassemble_find(rx->sdata, frag, seq, rx->queue, hdr); | 1027 | entry = ieee80211_reassemble_find(rx->sdata, frag, seq, rx->queue, hdr); |
1024 | if (!entry) { | 1028 | if (!entry) { |
1025 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 1029 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
1026 | return RX_DROP_MONITOR; | 1030 | return RX_DROP_MONITOR; |
1027 | } | 1031 | } |
1028 | 1032 | ||
1029 | /* Verify that MPDUs within one MSDU have sequential PN values. | 1033 | /* Verify that MPDUs within one MSDU have sequential PN values. |
1030 | * (IEEE 802.11i, 8.3.3.4.5) */ | 1034 | * (IEEE 802.11i, 8.3.3.4.5) */ |
1031 | if (entry->ccmp) { | 1035 | if (entry->ccmp) { |
1032 | int i; | 1036 | int i; |
1033 | u8 pn[CCMP_PN_LEN], *rpn; | 1037 | u8 pn[CCMP_PN_LEN], *rpn; |
1034 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) | 1038 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) |
1035 | return RX_DROP_UNUSABLE; | 1039 | return RX_DROP_UNUSABLE; |
1036 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 1040 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); |
1037 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 1041 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { |
1038 | pn[i]++; | 1042 | pn[i]++; |
1039 | if (pn[i]) | 1043 | if (pn[i]) |
1040 | break; | 1044 | break; |
1041 | } | 1045 | } |
1042 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; | 1046 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; |
1043 | if (memcmp(pn, rpn, CCMP_PN_LEN)) | 1047 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
1044 | return RX_DROP_UNUSABLE; | 1048 | return RX_DROP_UNUSABLE; |
1045 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 1049 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
1046 | } | 1050 | } |
1047 | 1051 | ||
1048 | skb_pull(rx->skb, ieee80211_hdrlen(fc)); | 1052 | skb_pull(rx->skb, ieee80211_hdrlen(fc)); |
1049 | __skb_queue_tail(&entry->skb_list, rx->skb); | 1053 | __skb_queue_tail(&entry->skb_list, rx->skb); |
1050 | entry->last_frag = frag; | 1054 | entry->last_frag = frag; |
1051 | entry->extra_len += rx->skb->len; | 1055 | entry->extra_len += rx->skb->len; |
1052 | if (ieee80211_has_morefrags(fc)) { | 1056 | if (ieee80211_has_morefrags(fc)) { |
1053 | rx->skb = NULL; | 1057 | rx->skb = NULL; |
1054 | return RX_QUEUED; | 1058 | return RX_QUEUED; |
1055 | } | 1059 | } |
1056 | 1060 | ||
1057 | rx->skb = __skb_dequeue(&entry->skb_list); | 1061 | rx->skb = __skb_dequeue(&entry->skb_list); |
1058 | if (skb_tailroom(rx->skb) < entry->extra_len) { | 1062 | if (skb_tailroom(rx->skb) < entry->extra_len) { |
1059 | I802_DEBUG_INC(rx->local->rx_expand_skb_head2); | 1063 | I802_DEBUG_INC(rx->local->rx_expand_skb_head2); |
1060 | if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len, | 1064 | if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len, |
1061 | GFP_ATOMIC))) { | 1065 | GFP_ATOMIC))) { |
1062 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 1066 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
1063 | __skb_queue_purge(&entry->skb_list); | 1067 | __skb_queue_purge(&entry->skb_list); |
1064 | return RX_DROP_UNUSABLE; | 1068 | return RX_DROP_UNUSABLE; |
1065 | } | 1069 | } |
1066 | } | 1070 | } |
1067 | while ((skb = __skb_dequeue(&entry->skb_list))) { | 1071 | while ((skb = __skb_dequeue(&entry->skb_list))) { |
1068 | memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len); | 1072 | memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len); |
1069 | dev_kfree_skb(skb); | 1073 | dev_kfree_skb(skb); |
1070 | } | 1074 | } |
1071 | 1075 | ||
1072 | /* Complete frame has been reassembled - process it now */ | 1076 | /* Complete frame has been reassembled - process it now */ |
1073 | rx->flags |= IEEE80211_RX_FRAGMENTED; | 1077 | rx->flags |= IEEE80211_RX_FRAGMENTED; |
1074 | 1078 | ||
1075 | out: | 1079 | out: |
1076 | if (rx->sta) | 1080 | if (rx->sta) |
1077 | rx->sta->rx_packets++; | 1081 | rx->sta->rx_packets++; |
1078 | if (is_multicast_ether_addr(hdr->addr1)) | 1082 | if (is_multicast_ether_addr(hdr->addr1)) |
1079 | rx->local->dot11MulticastReceivedFrameCount++; | 1083 | rx->local->dot11MulticastReceivedFrameCount++; |
1080 | else | 1084 | else |
1081 | ieee80211_led_rx(rx->local); | 1085 | ieee80211_led_rx(rx->local); |
1082 | return RX_CONTINUE; | 1086 | return RX_CONTINUE; |
1083 | } | 1087 | } |
1084 | 1088 | ||
1085 | static ieee80211_rx_result debug_noinline | 1089 | static ieee80211_rx_result debug_noinline |
1086 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 1090 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
1087 | { | 1091 | { |
1088 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1092 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1089 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 1093 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
1090 | 1094 | ||
1091 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 1095 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
1092 | !(rx->flags & IEEE80211_RX_RA_MATCH))) | 1096 | !(rx->flags & IEEE80211_RX_RA_MATCH))) |
1093 | return RX_CONTINUE; | 1097 | return RX_CONTINUE; |
1094 | 1098 | ||
1095 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && | 1099 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && |
1096 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) | 1100 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) |
1097 | return RX_DROP_UNUSABLE; | 1101 | return RX_DROP_UNUSABLE; |
1098 | 1102 | ||
1099 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) | 1103 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) |
1100 | ieee80211_sta_ps_deliver_poll_response(rx->sta); | 1104 | ieee80211_sta_ps_deliver_poll_response(rx->sta); |
1101 | else | 1105 | else |
1102 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 1106 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
1103 | 1107 | ||
1104 | /* Free PS Poll skb here instead of returning RX_DROP that would | 1108 | /* Free PS Poll skb here instead of returning RX_DROP that would |
1105 | * count as an dropped frame. */ | 1109 | * count as an dropped frame. */ |
1106 | dev_kfree_skb(rx->skb); | 1110 | dev_kfree_skb(rx->skb); |
1107 | 1111 | ||
1108 | return RX_QUEUED; | 1112 | return RX_QUEUED; |
1109 | } | 1113 | } |
1110 | 1114 | ||
1111 | static ieee80211_rx_result debug_noinline | 1115 | static ieee80211_rx_result debug_noinline |
1112 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1116 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
1113 | { | 1117 | { |
1114 | u8 *data = rx->skb->data; | 1118 | u8 *data = rx->skb->data; |
1115 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data; | 1119 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data; |
1116 | 1120 | ||
1117 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 1121 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
1118 | return RX_CONTINUE; | 1122 | return RX_CONTINUE; |
1119 | 1123 | ||
1120 | /* remove the qos control field, update frame type and meta-data */ | 1124 | /* remove the qos control field, update frame type and meta-data */ |
1121 | memmove(data + IEEE80211_QOS_CTL_LEN, data, | 1125 | memmove(data + IEEE80211_QOS_CTL_LEN, data, |
1122 | ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN); | 1126 | ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN); |
1123 | hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN); | 1127 | hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN); |
1124 | /* change frame type to non QOS */ | 1128 | /* change frame type to non QOS */ |
1125 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | 1129 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
1126 | 1130 | ||
1127 | return RX_CONTINUE; | 1131 | return RX_CONTINUE; |
1128 | } | 1132 | } |
1129 | 1133 | ||
1130 | static int | 1134 | static int |
1131 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1135 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1132 | { | 1136 | { |
1133 | if (unlikely(!rx->sta || | 1137 | if (unlikely(!rx->sta || |
1134 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) | 1138 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) |
1135 | return -EACCES; | 1139 | return -EACCES; |
1136 | 1140 | ||
1137 | return 0; | 1141 | return 0; |
1138 | } | 1142 | } |
1139 | 1143 | ||
1140 | static int | 1144 | static int |
1141 | ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) | 1145 | ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) |
1142 | { | 1146 | { |
1147 | struct sk_buff *skb = rx->skb; | ||
1148 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1149 | |||
1143 | /* | 1150 | /* |
1144 | * Pass through unencrypted frames if the hardware has | 1151 | * Pass through unencrypted frames if the hardware has |
1145 | * decrypted them already. | 1152 | * decrypted them already. |
1146 | */ | 1153 | */ |
1147 | if (rx->status->flag & RX_FLAG_DECRYPTED) | 1154 | if (status->flag & RX_FLAG_DECRYPTED) |
1148 | return 0; | 1155 | return 0; |
1149 | 1156 | ||
1150 | /* Drop unencrypted frames if key is set. */ | 1157 | /* Drop unencrypted frames if key is set. */ |
1151 | if (unlikely(!ieee80211_has_protected(fc) && | 1158 | if (unlikely(!ieee80211_has_protected(fc) && |
1152 | !ieee80211_is_nullfunc(fc) && | 1159 | !ieee80211_is_nullfunc(fc) && |
1153 | ieee80211_is_data(fc) && | 1160 | ieee80211_is_data(fc) && |
1154 | (rx->key || rx->sdata->drop_unencrypted))) | 1161 | (rx->key || rx->sdata->drop_unencrypted))) |
1155 | return -EACCES; | 1162 | return -EACCES; |
1156 | if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { | 1163 | if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { |
1157 | if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && | 1164 | if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && |
1158 | rx->key)) | 1165 | rx->key)) |
1159 | return -EACCES; | 1166 | return -EACCES; |
1160 | /* BIP does not use Protected field, so need to check MMIE */ | 1167 | /* BIP does not use Protected field, so need to check MMIE */ |
1161 | if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) | 1168 | if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) |
1162 | && ieee80211_get_mmie_keyidx(rx->skb) < 0 && | 1169 | && ieee80211_get_mmie_keyidx(rx->skb) < 0 && |
1163 | rx->key)) | 1170 | rx->key)) |
1164 | return -EACCES; | 1171 | return -EACCES; |
1165 | /* | 1172 | /* |
1166 | * When using MFP, Action frames are not allowed prior to | 1173 | * When using MFP, Action frames are not allowed prior to |
1167 | * having configured keys. | 1174 | * having configured keys. |
1168 | */ | 1175 | */ |
1169 | if (unlikely(ieee80211_is_action(fc) && !rx->key && | 1176 | if (unlikely(ieee80211_is_action(fc) && !rx->key && |
1170 | ieee80211_is_robust_mgmt_frame( | 1177 | ieee80211_is_robust_mgmt_frame( |
1171 | (struct ieee80211_hdr *) rx->skb->data))) | 1178 | (struct ieee80211_hdr *) rx->skb->data))) |
1172 | return -EACCES; | 1179 | return -EACCES; |
1173 | } | 1180 | } |
1174 | 1181 | ||
1175 | return 0; | 1182 | return 0; |
1176 | } | 1183 | } |
1177 | 1184 | ||
1178 | static int | 1185 | static int |
1179 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | 1186 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) |
1180 | { | 1187 | { |
1181 | struct net_device *dev = rx->dev; | 1188 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1182 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1189 | struct net_device *dev = sdata->dev; |
1183 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1190 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1184 | 1191 | ||
1185 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && | 1192 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && |
1186 | ieee80211_has_a4(hdr->frame_control)) | 1193 | ieee80211_has_a4(hdr->frame_control)) |
1187 | return -1; | 1194 | return -1; |
1188 | if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1)) | 1195 | if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1)) |
1189 | return -1; | 1196 | return -1; |
1190 | 1197 | ||
1191 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); | 1198 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); |
1192 | } | 1199 | } |
1193 | 1200 | ||
1194 | /* | 1201 | /* |
1195 | * requires that rx->skb is a frame with ethernet header | 1202 | * requires that rx->skb is a frame with ethernet header |
1196 | */ | 1203 | */ |
1197 | static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) | 1204 | static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) |
1198 | { | 1205 | { |
1199 | static const u8 pae_group_addr[ETH_ALEN] __aligned(2) | 1206 | static const u8 pae_group_addr[ETH_ALEN] __aligned(2) |
1200 | = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 }; | 1207 | = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 }; |
1201 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1208 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1202 | 1209 | ||
1203 | /* | 1210 | /* |
1204 | * Allow EAPOL frames to us/the PAE group address regardless | 1211 | * Allow EAPOL frames to us/the PAE group address regardless |
1205 | * of whether the frame was encrypted or not. | 1212 | * of whether the frame was encrypted or not. |
1206 | */ | 1213 | */ |
1207 | if (ehdr->h_proto == htons(ETH_P_PAE) && | 1214 | if (ehdr->h_proto == htons(ETH_P_PAE) && |
1208 | (compare_ether_addr(ehdr->h_dest, rx->dev->dev_addr) == 0 || | 1215 | (compare_ether_addr(ehdr->h_dest, rx->sdata->dev->dev_addr) == 0 || |
1209 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) | 1216 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) |
1210 | return true; | 1217 | return true; |
1211 | 1218 | ||
1212 | if (ieee80211_802_1x_port_control(rx) || | 1219 | if (ieee80211_802_1x_port_control(rx) || |
1213 | ieee80211_drop_unencrypted(rx, fc)) | 1220 | ieee80211_drop_unencrypted(rx, fc)) |
1214 | return false; | 1221 | return false; |
1215 | 1222 | ||
1216 | return true; | 1223 | return true; |
1217 | } | 1224 | } |
1218 | 1225 | ||
1219 | /* | 1226 | /* |
1220 | * requires that rx->skb is a frame with ethernet header | 1227 | * requires that rx->skb is a frame with ethernet header |
1221 | */ | 1228 | */ |
1222 | static void | 1229 | static void |
1223 | ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | 1230 | ieee80211_deliver_skb(struct ieee80211_rx_data *rx) |
1224 | { | 1231 | { |
1225 | struct net_device *dev = rx->dev; | 1232 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1233 | struct net_device *dev = sdata->dev; | ||
1226 | struct ieee80211_local *local = rx->local; | 1234 | struct ieee80211_local *local = rx->local; |
1227 | struct sk_buff *skb, *xmit_skb; | 1235 | struct sk_buff *skb, *xmit_skb; |
1228 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1229 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1236 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1230 | struct sta_info *dsta; | 1237 | struct sta_info *dsta; |
1231 | 1238 | ||
1232 | skb = rx->skb; | 1239 | skb = rx->skb; |
1233 | xmit_skb = NULL; | 1240 | xmit_skb = NULL; |
1234 | 1241 | ||
1235 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1242 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1236 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1243 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1237 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1244 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1238 | (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) { | 1245 | (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) { |
1239 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1246 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1240 | /* | 1247 | /* |
1241 | * send multicast frames both to higher layers in | 1248 | * send multicast frames both to higher layers in |
1242 | * local net stack and back to the wireless medium | 1249 | * local net stack and back to the wireless medium |
1243 | */ | 1250 | */ |
1244 | xmit_skb = skb_copy(skb, GFP_ATOMIC); | 1251 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
1245 | if (!xmit_skb && net_ratelimit()) | 1252 | if (!xmit_skb && net_ratelimit()) |
1246 | printk(KERN_DEBUG "%s: failed to clone " | 1253 | printk(KERN_DEBUG "%s: failed to clone " |
1247 | "multicast frame\n", dev->name); | 1254 | "multicast frame\n", dev->name); |
1248 | } else { | 1255 | } else { |
1249 | dsta = sta_info_get(local, skb->data); | 1256 | dsta = sta_info_get(local, skb->data); |
1250 | if (dsta && dsta->sdata->dev == dev) { | 1257 | if (dsta && dsta->sdata->dev == dev) { |
1251 | /* | 1258 | /* |
1252 | * The destination station is associated to | 1259 | * The destination station is associated to |
1253 | * this AP (in this VLAN), so send the frame | 1260 | * this AP (in this VLAN), so send the frame |
1254 | * directly to it and do not pass it to local | 1261 | * directly to it and do not pass it to local |
1255 | * net stack. | 1262 | * net stack. |
1256 | */ | 1263 | */ |
1257 | xmit_skb = skb; | 1264 | xmit_skb = skb; |
1258 | skb = NULL; | 1265 | skb = NULL; |
1259 | } | 1266 | } |
1260 | } | 1267 | } |
1261 | } | 1268 | } |
1262 | 1269 | ||
1263 | if (skb) { | 1270 | if (skb) { |
1264 | int align __maybe_unused; | 1271 | int align __maybe_unused; |
1265 | 1272 | ||
1266 | #if defined(CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT) || !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | 1273 | #if defined(CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT) || !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
1267 | /* | 1274 | /* |
1268 | * 'align' will only take the values 0 or 2 here | 1275 | * 'align' will only take the values 0 or 2 here |
1269 | * since all frames are required to be aligned | 1276 | * since all frames are required to be aligned |
1270 | * to 2-byte boundaries when being passed to | 1277 | * to 2-byte boundaries when being passed to |
1271 | * mac80211. That also explains the __skb_push() | 1278 | * mac80211. That also explains the __skb_push() |
1272 | * below. | 1279 | * below. |
1273 | */ | 1280 | */ |
1274 | align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; | 1281 | align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; |
1275 | if (align) { | 1282 | if (align) { |
1276 | if (WARN_ON(skb_headroom(skb) < 3)) { | 1283 | if (WARN_ON(skb_headroom(skb) < 3)) { |
1277 | dev_kfree_skb(skb); | 1284 | dev_kfree_skb(skb); |
1278 | skb = NULL; | 1285 | skb = NULL; |
1279 | } else { | 1286 | } else { |
1280 | u8 *data = skb->data; | 1287 | u8 *data = skb->data; |
1281 | size_t len = skb_headlen(skb); | 1288 | size_t len = skb_headlen(skb); |
1282 | skb->data -= align; | 1289 | skb->data -= align; |
1283 | memmove(skb->data, data, len); | 1290 | memmove(skb->data, data, len); |
1284 | skb_set_tail_pointer(skb, len); | 1291 | skb_set_tail_pointer(skb, len); |
1285 | } | 1292 | } |
1286 | } | 1293 | } |
1287 | #endif | 1294 | #endif |
1288 | 1295 | ||
1289 | if (skb) { | 1296 | if (skb) { |
1290 | /* deliver to local stack */ | 1297 | /* deliver to local stack */ |
1291 | skb->protocol = eth_type_trans(skb, dev); | 1298 | skb->protocol = eth_type_trans(skb, dev); |
1292 | memset(skb->cb, 0, sizeof(skb->cb)); | 1299 | memset(skb->cb, 0, sizeof(skb->cb)); |
1293 | netif_rx(skb); | 1300 | netif_rx(skb); |
1294 | } | 1301 | } |
1295 | } | 1302 | } |
1296 | 1303 | ||
1297 | if (xmit_skb) { | 1304 | if (xmit_skb) { |
1298 | /* send to wireless media */ | 1305 | /* send to wireless media */ |
1299 | xmit_skb->protocol = htons(ETH_P_802_3); | 1306 | xmit_skb->protocol = htons(ETH_P_802_3); |
1300 | skb_reset_network_header(xmit_skb); | 1307 | skb_reset_network_header(xmit_skb); |
1301 | skb_reset_mac_header(xmit_skb); | 1308 | skb_reset_mac_header(xmit_skb); |
1302 | dev_queue_xmit(xmit_skb); | 1309 | dev_queue_xmit(xmit_skb); |
1303 | } | 1310 | } |
1304 | } | 1311 | } |
1305 | 1312 | ||
1306 | static ieee80211_rx_result debug_noinline | 1313 | static ieee80211_rx_result debug_noinline |
1307 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1314 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
1308 | { | 1315 | { |
1309 | struct net_device *dev = rx->dev; | 1316 | struct net_device *dev = rx->sdata->dev; |
1310 | struct ieee80211_local *local = rx->local; | 1317 | struct ieee80211_local *local = rx->local; |
1311 | u16 ethertype; | 1318 | u16 ethertype; |
1312 | u8 *payload; | 1319 | u8 *payload; |
1313 | struct sk_buff *skb = rx->skb, *frame = NULL; | 1320 | struct sk_buff *skb = rx->skb, *frame = NULL; |
1314 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1321 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1315 | __le16 fc = hdr->frame_control; | 1322 | __le16 fc = hdr->frame_control; |
1316 | const struct ethhdr *eth; | 1323 | const struct ethhdr *eth; |
1317 | int remaining, err; | 1324 | int remaining, err; |
1318 | u8 dst[ETH_ALEN]; | 1325 | u8 dst[ETH_ALEN]; |
1319 | u8 src[ETH_ALEN]; | 1326 | u8 src[ETH_ALEN]; |
1320 | 1327 | ||
1321 | if (unlikely(!ieee80211_is_data(fc))) | 1328 | if (unlikely(!ieee80211_is_data(fc))) |
1322 | return RX_CONTINUE; | 1329 | return RX_CONTINUE; |
1323 | 1330 | ||
1324 | if (unlikely(!ieee80211_is_data_present(fc))) | 1331 | if (unlikely(!ieee80211_is_data_present(fc))) |
1325 | return RX_DROP_MONITOR; | 1332 | return RX_DROP_MONITOR; |
1326 | 1333 | ||
1327 | if (!(rx->flags & IEEE80211_RX_AMSDU)) | 1334 | if (!(rx->flags & IEEE80211_RX_AMSDU)) |
1328 | return RX_CONTINUE; | 1335 | return RX_CONTINUE; |
1329 | 1336 | ||
1330 | err = __ieee80211_data_to_8023(rx); | 1337 | err = __ieee80211_data_to_8023(rx); |
1331 | if (unlikely(err)) | 1338 | if (unlikely(err)) |
1332 | return RX_DROP_UNUSABLE; | 1339 | return RX_DROP_UNUSABLE; |
1333 | 1340 | ||
1334 | skb->dev = dev; | 1341 | skb->dev = dev; |
1335 | 1342 | ||
1336 | dev->stats.rx_packets++; | 1343 | dev->stats.rx_packets++; |
1337 | dev->stats.rx_bytes += skb->len; | 1344 | dev->stats.rx_bytes += skb->len; |
1338 | 1345 | ||
1339 | /* skip the wrapping header */ | 1346 | /* skip the wrapping header */ |
1340 | eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); | 1347 | eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); |
1341 | if (!eth) | 1348 | if (!eth) |
1342 | return RX_DROP_UNUSABLE; | 1349 | return RX_DROP_UNUSABLE; |
1343 | 1350 | ||
1344 | while (skb != frame) { | 1351 | while (skb != frame) { |
1345 | u8 padding; | 1352 | u8 padding; |
1346 | __be16 len = eth->h_proto; | 1353 | __be16 len = eth->h_proto; |
1347 | unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len); | 1354 | unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len); |
1348 | 1355 | ||
1349 | remaining = skb->len; | 1356 | remaining = skb->len; |
1350 | memcpy(dst, eth->h_dest, ETH_ALEN); | 1357 | memcpy(dst, eth->h_dest, ETH_ALEN); |
1351 | memcpy(src, eth->h_source, ETH_ALEN); | 1358 | memcpy(src, eth->h_source, ETH_ALEN); |
1352 | 1359 | ||
1353 | padding = ((4 - subframe_len) & 0x3); | 1360 | padding = ((4 - subframe_len) & 0x3); |
1354 | /* the last MSDU has no padding */ | 1361 | /* the last MSDU has no padding */ |
1355 | if (subframe_len > remaining) | 1362 | if (subframe_len > remaining) |
1356 | return RX_DROP_UNUSABLE; | 1363 | return RX_DROP_UNUSABLE; |
1357 | 1364 | ||
1358 | skb_pull(skb, sizeof(struct ethhdr)); | 1365 | skb_pull(skb, sizeof(struct ethhdr)); |
1359 | /* if last subframe reuse skb */ | 1366 | /* if last subframe reuse skb */ |
1360 | if (remaining <= subframe_len + padding) | 1367 | if (remaining <= subframe_len + padding) |
1361 | frame = skb; | 1368 | frame = skb; |
1362 | else { | 1369 | else { |
1363 | /* | 1370 | /* |
1364 | * Allocate and reserve two bytes more for payload | 1371 | * Allocate and reserve two bytes more for payload |
1365 | * alignment since sizeof(struct ethhdr) is 14. | 1372 | * alignment since sizeof(struct ethhdr) is 14. |
1366 | */ | 1373 | */ |
1367 | frame = dev_alloc_skb( | 1374 | frame = dev_alloc_skb( |
1368 | ALIGN(local->hw.extra_tx_headroom, 4) + | 1375 | ALIGN(local->hw.extra_tx_headroom, 4) + |
1369 | subframe_len + 2); | 1376 | subframe_len + 2); |
1370 | 1377 | ||
1371 | if (frame == NULL) | 1378 | if (frame == NULL) |
1372 | return RX_DROP_UNUSABLE; | 1379 | return RX_DROP_UNUSABLE; |
1373 | 1380 | ||
1374 | skb_reserve(frame, | 1381 | skb_reserve(frame, |
1375 | ALIGN(local->hw.extra_tx_headroom, 4) + | 1382 | ALIGN(local->hw.extra_tx_headroom, 4) + |
1376 | sizeof(struct ethhdr) + 2); | 1383 | sizeof(struct ethhdr) + 2); |
1377 | memcpy(skb_put(frame, ntohs(len)), skb->data, | 1384 | memcpy(skb_put(frame, ntohs(len)), skb->data, |
1378 | ntohs(len)); | 1385 | ntohs(len)); |
1379 | 1386 | ||
1380 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + | 1387 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + |
1381 | padding); | 1388 | padding); |
1382 | if (!eth) { | 1389 | if (!eth) { |
1383 | dev_kfree_skb(frame); | 1390 | dev_kfree_skb(frame); |
1384 | return RX_DROP_UNUSABLE; | 1391 | return RX_DROP_UNUSABLE; |
1385 | } | 1392 | } |
1386 | } | 1393 | } |
1387 | 1394 | ||
1388 | skb_reset_network_header(frame); | 1395 | skb_reset_network_header(frame); |
1389 | frame->dev = dev; | 1396 | frame->dev = dev; |
1390 | frame->priority = skb->priority; | 1397 | frame->priority = skb->priority; |
1391 | rx->skb = frame; | 1398 | rx->skb = frame; |
1392 | 1399 | ||
1393 | payload = frame->data; | 1400 | payload = frame->data; |
1394 | ethertype = (payload[6] << 8) | payload[7]; | 1401 | ethertype = (payload[6] << 8) | payload[7]; |
1395 | 1402 | ||
1396 | if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && | 1403 | if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && |
1397 | ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || | 1404 | ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || |
1398 | compare_ether_addr(payload, | 1405 | compare_ether_addr(payload, |
1399 | bridge_tunnel_header) == 0)) { | 1406 | bridge_tunnel_header) == 0)) { |
1400 | /* remove RFC1042 or Bridge-Tunnel | 1407 | /* remove RFC1042 or Bridge-Tunnel |
1401 | * encapsulation and replace EtherType */ | 1408 | * encapsulation and replace EtherType */ |
1402 | skb_pull(frame, 6); | 1409 | skb_pull(frame, 6); |
1403 | memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); | 1410 | memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); |
1404 | memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); | 1411 | memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); |
1405 | } else { | 1412 | } else { |
1406 | memcpy(skb_push(frame, sizeof(__be16)), | 1413 | memcpy(skb_push(frame, sizeof(__be16)), |
1407 | &len, sizeof(__be16)); | 1414 | &len, sizeof(__be16)); |
1408 | memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); | 1415 | memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); |
1409 | memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); | 1416 | memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); |
1410 | } | 1417 | } |
1411 | 1418 | ||
1412 | if (!ieee80211_frame_allowed(rx, fc)) { | 1419 | if (!ieee80211_frame_allowed(rx, fc)) { |
1413 | if (skb == frame) /* last frame */ | 1420 | if (skb == frame) /* last frame */ |
1414 | return RX_DROP_UNUSABLE; | 1421 | return RX_DROP_UNUSABLE; |
1415 | dev_kfree_skb(frame); | 1422 | dev_kfree_skb(frame); |
1416 | continue; | 1423 | continue; |
1417 | } | 1424 | } |
1418 | 1425 | ||
1419 | ieee80211_deliver_skb(rx); | 1426 | ieee80211_deliver_skb(rx); |
1420 | } | 1427 | } |
1421 | 1428 | ||
1422 | return RX_QUEUED; | 1429 | return RX_QUEUED; |
1423 | } | 1430 | } |
1424 | 1431 | ||
1425 | #ifdef CONFIG_MAC80211_MESH | 1432 | #ifdef CONFIG_MAC80211_MESH |
1426 | static ieee80211_rx_result | 1433 | static ieee80211_rx_result |
1427 | ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | 1434 | ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) |
1428 | { | 1435 | { |
1429 | struct ieee80211_hdr *hdr; | 1436 | struct ieee80211_hdr *hdr; |
1430 | struct ieee80211s_hdr *mesh_hdr; | 1437 | struct ieee80211s_hdr *mesh_hdr; |
1431 | unsigned int hdrlen; | 1438 | unsigned int hdrlen; |
1432 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1439 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1433 | struct ieee80211_local *local = rx->local; | 1440 | struct ieee80211_local *local = rx->local; |
1434 | struct ieee80211_sub_if_data *sdata; | 1441 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1435 | 1442 | ||
1436 | hdr = (struct ieee80211_hdr *) skb->data; | 1443 | hdr = (struct ieee80211_hdr *) skb->data; |
1437 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1444 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1438 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 1445 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
1439 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | ||
1440 | 1446 | ||
1441 | if (!ieee80211_is_data(hdr->frame_control)) | 1447 | if (!ieee80211_is_data(hdr->frame_control)) |
1442 | return RX_CONTINUE; | 1448 | return RX_CONTINUE; |
1443 | 1449 | ||
1444 | if (!mesh_hdr->ttl) | 1450 | if (!mesh_hdr->ttl) |
1445 | /* illegal frame */ | 1451 | /* illegal frame */ |
1446 | return RX_DROP_MONITOR; | 1452 | return RX_DROP_MONITOR; |
1447 | 1453 | ||
1448 | if (mesh_hdr->flags & MESH_FLAGS_AE) { | 1454 | if (mesh_hdr->flags & MESH_FLAGS_AE) { |
1449 | struct mesh_path *mppath; | 1455 | struct mesh_path *mppath; |
1450 | char *proxied_addr; | 1456 | char *proxied_addr; |
1451 | char *mpp_addr; | 1457 | char *mpp_addr; |
1452 | 1458 | ||
1453 | if (is_multicast_ether_addr(hdr->addr1)) { | 1459 | if (is_multicast_ether_addr(hdr->addr1)) { |
1454 | mpp_addr = hdr->addr3; | 1460 | mpp_addr = hdr->addr3; |
1455 | proxied_addr = mesh_hdr->eaddr1; | 1461 | proxied_addr = mesh_hdr->eaddr1; |
1456 | } else { | 1462 | } else { |
1457 | mpp_addr = hdr->addr4; | 1463 | mpp_addr = hdr->addr4; |
1458 | proxied_addr = mesh_hdr->eaddr2; | 1464 | proxied_addr = mesh_hdr->eaddr2; |
1459 | } | 1465 | } |
1460 | 1466 | ||
1461 | rcu_read_lock(); | 1467 | rcu_read_lock(); |
1462 | mppath = mpp_path_lookup(proxied_addr, sdata); | 1468 | mppath = mpp_path_lookup(proxied_addr, sdata); |
1463 | if (!mppath) { | 1469 | if (!mppath) { |
1464 | mpp_path_add(proxied_addr, mpp_addr, sdata); | 1470 | mpp_path_add(proxied_addr, mpp_addr, sdata); |
1465 | } else { | 1471 | } else { |
1466 | spin_lock_bh(&mppath->state_lock); | 1472 | spin_lock_bh(&mppath->state_lock); |
1467 | mppath->exp_time = jiffies; | 1473 | mppath->exp_time = jiffies; |
1468 | if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) | 1474 | if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) |
1469 | memcpy(mppath->mpp, mpp_addr, ETH_ALEN); | 1475 | memcpy(mppath->mpp, mpp_addr, ETH_ALEN); |
1470 | spin_unlock_bh(&mppath->state_lock); | 1476 | spin_unlock_bh(&mppath->state_lock); |
1471 | } | 1477 | } |
1472 | rcu_read_unlock(); | 1478 | rcu_read_unlock(); |
1473 | } | 1479 | } |
1474 | 1480 | ||
1475 | /* Frame has reached destination. Don't forward */ | 1481 | /* Frame has reached destination. Don't forward */ |
1476 | if (!is_multicast_ether_addr(hdr->addr1) && | 1482 | if (!is_multicast_ether_addr(hdr->addr1) && |
1477 | compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) | 1483 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr3) == 0) |
1478 | return RX_CONTINUE; | 1484 | return RX_CONTINUE; |
1479 | 1485 | ||
1480 | mesh_hdr->ttl--; | 1486 | mesh_hdr->ttl--; |
1481 | 1487 | ||
1482 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 1488 | if (rx->flags & IEEE80211_RX_RA_MATCH) { |
1483 | if (!mesh_hdr->ttl) | 1489 | if (!mesh_hdr->ttl) |
1484 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, | 1490 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, |
1485 | dropped_frames_ttl); | 1491 | dropped_frames_ttl); |
1486 | else { | 1492 | else { |
1487 | struct ieee80211_hdr *fwd_hdr; | 1493 | struct ieee80211_hdr *fwd_hdr; |
1488 | struct ieee80211_tx_info *info; | 1494 | struct ieee80211_tx_info *info; |
1489 | 1495 | ||
1490 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1496 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1491 | 1497 | ||
1492 | if (!fwd_skb && net_ratelimit()) | 1498 | if (!fwd_skb && net_ratelimit()) |
1493 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", | 1499 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", |
1494 | rx->dev->name); | 1500 | sdata->dev->name); |
1495 | 1501 | ||
1496 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 1502 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
1497 | memcpy(fwd_hdr->addr2, rx->dev->dev_addr, ETH_ALEN); | 1503 | memcpy(fwd_hdr->addr2, sdata->dev->dev_addr, ETH_ALEN); |
1498 | info = IEEE80211_SKB_CB(fwd_skb); | 1504 | info = IEEE80211_SKB_CB(fwd_skb); |
1499 | memset(info, 0, sizeof(*info)); | 1505 | memset(info, 0, sizeof(*info)); |
1500 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1506 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1501 | info->control.vif = &rx->sdata->vif; | 1507 | info->control.vif = &rx->sdata->vif; |
1502 | ieee80211_select_queue(local, fwd_skb); | 1508 | ieee80211_select_queue(local, fwd_skb); |
1503 | if (is_multicast_ether_addr(fwd_hdr->addr1)) | 1509 | if (is_multicast_ether_addr(fwd_hdr->addr1)) |
1504 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | 1510 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, |
1505 | fwded_mcast); | 1511 | fwded_mcast); |
1506 | else { | 1512 | else { |
1507 | int err; | 1513 | int err; |
1508 | /* | 1514 | /* |
1509 | * Save TA to addr1 to send TA a path error if a | 1515 | * Save TA to addr1 to send TA a path error if a |
1510 | * suitable next hop is not found | 1516 | * suitable next hop is not found |
1511 | */ | 1517 | */ |
1512 | memcpy(fwd_hdr->addr1, fwd_hdr->addr2, | 1518 | memcpy(fwd_hdr->addr1, fwd_hdr->addr2, |
1513 | ETH_ALEN); | 1519 | ETH_ALEN); |
1514 | err = mesh_nexthop_lookup(fwd_skb, sdata); | 1520 | err = mesh_nexthop_lookup(fwd_skb, sdata); |
1515 | /* Failed to immediately resolve next hop: | 1521 | /* Failed to immediately resolve next hop: |
1516 | * fwded frame was dropped or will be added | 1522 | * fwded frame was dropped or will be added |
1517 | * later to the pending skb queue. */ | 1523 | * later to the pending skb queue. */ |
1518 | if (err) | 1524 | if (err) |
1519 | return RX_DROP_MONITOR; | 1525 | return RX_DROP_MONITOR; |
1520 | 1526 | ||
1521 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | 1527 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, |
1522 | fwded_unicast); | 1528 | fwded_unicast); |
1523 | } | 1529 | } |
1524 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | 1530 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, |
1525 | fwded_frames); | 1531 | fwded_frames); |
1526 | ieee80211_add_pending_skb(local, fwd_skb); | 1532 | ieee80211_add_pending_skb(local, fwd_skb); |
1527 | } | 1533 | } |
1528 | } | 1534 | } |
1529 | 1535 | ||
1530 | if (is_multicast_ether_addr(hdr->addr1) || | 1536 | if (is_multicast_ether_addr(hdr->addr1) || |
1531 | rx->dev->flags & IFF_PROMISC) | 1537 | sdata->dev->flags & IFF_PROMISC) |
1532 | return RX_CONTINUE; | 1538 | return RX_CONTINUE; |
1533 | else | 1539 | else |
1534 | return RX_DROP_MONITOR; | 1540 | return RX_DROP_MONITOR; |
1535 | } | 1541 | } |
1536 | #endif | 1542 | #endif |
1537 | 1543 | ||
1538 | static ieee80211_rx_result debug_noinline | 1544 | static ieee80211_rx_result debug_noinline |
1539 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1545 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
1540 | { | 1546 | { |
1541 | struct net_device *dev = rx->dev; | 1547 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1548 | struct net_device *dev = sdata->dev; | ||
1542 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1549 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1543 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1544 | __le16 fc = hdr->frame_control; | 1550 | __le16 fc = hdr->frame_control; |
1545 | int err; | 1551 | int err; |
1546 | 1552 | ||
1547 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) | 1553 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) |
1548 | return RX_CONTINUE; | 1554 | return RX_CONTINUE; |
1549 | 1555 | ||
1550 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) | 1556 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |
1551 | return RX_DROP_MONITOR; | 1557 | return RX_DROP_MONITOR; |
1552 | 1558 | ||
1553 | /* | 1559 | /* |
1554 | * Allow the cooked monitor interface of an AP to see 4-addr frames so | 1560 | * Allow the cooked monitor interface of an AP to see 4-addr frames so |
1555 | * that a 4-addr station can be detected and moved into a separate VLAN | 1561 | * that a 4-addr station can be detected and moved into a separate VLAN |
1556 | */ | 1562 | */ |
1557 | if (ieee80211_has_a4(hdr->frame_control) && | 1563 | if (ieee80211_has_a4(hdr->frame_control) && |
1558 | sdata->vif.type == NL80211_IFTYPE_AP) | 1564 | sdata->vif.type == NL80211_IFTYPE_AP) |
1559 | return RX_DROP_MONITOR; | 1565 | return RX_DROP_MONITOR; |
1560 | 1566 | ||
1561 | err = __ieee80211_data_to_8023(rx); | 1567 | err = __ieee80211_data_to_8023(rx); |
1562 | if (unlikely(err)) | 1568 | if (unlikely(err)) |
1563 | return RX_DROP_UNUSABLE; | 1569 | return RX_DROP_UNUSABLE; |
1564 | 1570 | ||
1565 | if (!ieee80211_frame_allowed(rx, fc)) | 1571 | if (!ieee80211_frame_allowed(rx, fc)) |
1566 | return RX_DROP_MONITOR; | 1572 | return RX_DROP_MONITOR; |
1567 | 1573 | ||
1568 | rx->skb->dev = dev; | 1574 | rx->skb->dev = dev; |
1569 | 1575 | ||
1570 | dev->stats.rx_packets++; | 1576 | dev->stats.rx_packets++; |
1571 | dev->stats.rx_bytes += rx->skb->len; | 1577 | dev->stats.rx_bytes += rx->skb->len; |
1572 | 1578 | ||
1573 | ieee80211_deliver_skb(rx); | 1579 | ieee80211_deliver_skb(rx); |
1574 | 1580 | ||
1575 | return RX_QUEUED; | 1581 | return RX_QUEUED; |
1576 | } | 1582 | } |
1577 | 1583 | ||
1578 | static ieee80211_rx_result debug_noinline | 1584 | static ieee80211_rx_result debug_noinline |
1579 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 1585 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
1580 | { | 1586 | { |
1581 | struct ieee80211_local *local = rx->local; | 1587 | struct ieee80211_local *local = rx->local; |
1582 | struct ieee80211_hw *hw = &local->hw; | 1588 | struct ieee80211_hw *hw = &local->hw; |
1583 | struct sk_buff *skb = rx->skb; | 1589 | struct sk_buff *skb = rx->skb; |
1584 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; | 1590 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
1585 | struct tid_ampdu_rx *tid_agg_rx; | 1591 | struct tid_ampdu_rx *tid_agg_rx; |
1586 | u16 start_seq_num; | 1592 | u16 start_seq_num; |
1587 | u16 tid; | 1593 | u16 tid; |
1588 | 1594 | ||
1589 | if (likely(!ieee80211_is_ctl(bar->frame_control))) | 1595 | if (likely(!ieee80211_is_ctl(bar->frame_control))) |
1590 | return RX_CONTINUE; | 1596 | return RX_CONTINUE; |
1591 | 1597 | ||
1592 | if (ieee80211_is_back_req(bar->frame_control)) { | 1598 | if (ieee80211_is_back_req(bar->frame_control)) { |
1593 | if (!rx->sta) | 1599 | if (!rx->sta) |
1594 | return RX_DROP_MONITOR; | 1600 | return RX_DROP_MONITOR; |
1595 | tid = le16_to_cpu(bar->control) >> 12; | 1601 | tid = le16_to_cpu(bar->control) >> 12; |
1596 | if (rx->sta->ampdu_mlme.tid_state_rx[tid] | 1602 | if (rx->sta->ampdu_mlme.tid_state_rx[tid] |
1597 | != HT_AGG_STATE_OPERATIONAL) | 1603 | != HT_AGG_STATE_OPERATIONAL) |
1598 | return RX_DROP_MONITOR; | 1604 | return RX_DROP_MONITOR; |
1599 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; | 1605 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; |
1600 | 1606 | ||
1601 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; | 1607 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; |
1602 | 1608 | ||
1603 | /* reset session timer */ | 1609 | /* reset session timer */ |
1604 | if (tid_agg_rx->timeout) | 1610 | if (tid_agg_rx->timeout) |
1605 | mod_timer(&tid_agg_rx->session_timer, | 1611 | mod_timer(&tid_agg_rx->session_timer, |
1606 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); | 1612 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); |
1607 | 1613 | ||
1608 | /* release stored frames up to start of BAR */ | 1614 | /* release stored frames up to start of BAR */ |
1609 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); | 1615 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); |
1610 | kfree_skb(skb); | 1616 | kfree_skb(skb); |
1611 | return RX_QUEUED; | 1617 | return RX_QUEUED; |
1612 | } | 1618 | } |
1613 | 1619 | ||
1614 | return RX_CONTINUE; | 1620 | return RX_CONTINUE; |
1615 | } | 1621 | } |
1616 | 1622 | ||
1617 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | 1623 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, |
1618 | struct ieee80211_mgmt *mgmt, | 1624 | struct ieee80211_mgmt *mgmt, |
1619 | size_t len) | 1625 | size_t len) |
1620 | { | 1626 | { |
1621 | struct ieee80211_local *local = sdata->local; | 1627 | struct ieee80211_local *local = sdata->local; |
1622 | struct sk_buff *skb; | 1628 | struct sk_buff *skb; |
1623 | struct ieee80211_mgmt *resp; | 1629 | struct ieee80211_mgmt *resp; |
1624 | 1630 | ||
1625 | if (compare_ether_addr(mgmt->da, sdata->dev->dev_addr) != 0) { | 1631 | if (compare_ether_addr(mgmt->da, sdata->dev->dev_addr) != 0) { |
1626 | /* Not to own unicast address */ | 1632 | /* Not to own unicast address */ |
1627 | return; | 1633 | return; |
1628 | } | 1634 | } |
1629 | 1635 | ||
1630 | if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 || | 1636 | if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 || |
1631 | compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) { | 1637 | compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) { |
1632 | /* Not from the current AP or not associated yet. */ | 1638 | /* Not from the current AP or not associated yet. */ |
1633 | return; | 1639 | return; |
1634 | } | 1640 | } |
1635 | 1641 | ||
1636 | if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) { | 1642 | if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) { |
1637 | /* Too short SA Query request frame */ | 1643 | /* Too short SA Query request frame */ |
1638 | return; | 1644 | return; |
1639 | } | 1645 | } |
1640 | 1646 | ||
1641 | skb = dev_alloc_skb(sizeof(*resp) + local->hw.extra_tx_headroom); | 1647 | skb = dev_alloc_skb(sizeof(*resp) + local->hw.extra_tx_headroom); |
1642 | if (skb == NULL) | 1648 | if (skb == NULL) |
1643 | return; | 1649 | return; |
1644 | 1650 | ||
1645 | skb_reserve(skb, local->hw.extra_tx_headroom); | 1651 | skb_reserve(skb, local->hw.extra_tx_headroom); |
1646 | resp = (struct ieee80211_mgmt *) skb_put(skb, 24); | 1652 | resp = (struct ieee80211_mgmt *) skb_put(skb, 24); |
1647 | memset(resp, 0, 24); | 1653 | memset(resp, 0, 24); |
1648 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 1654 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
1649 | memcpy(resp->sa, sdata->dev->dev_addr, ETH_ALEN); | 1655 | memcpy(resp->sa, sdata->dev->dev_addr, ETH_ALEN); |
1650 | memcpy(resp->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 1656 | memcpy(resp->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
1651 | resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 1657 | resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
1652 | IEEE80211_STYPE_ACTION); | 1658 | IEEE80211_STYPE_ACTION); |
1653 | skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query)); | 1659 | skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query)); |
1654 | resp->u.action.category = WLAN_CATEGORY_SA_QUERY; | 1660 | resp->u.action.category = WLAN_CATEGORY_SA_QUERY; |
1655 | resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE; | 1661 | resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE; |
1656 | memcpy(resp->u.action.u.sa_query.trans_id, | 1662 | memcpy(resp->u.action.u.sa_query.trans_id, |
1657 | mgmt->u.action.u.sa_query.trans_id, | 1663 | mgmt->u.action.u.sa_query.trans_id, |
1658 | WLAN_SA_QUERY_TR_ID_LEN); | 1664 | WLAN_SA_QUERY_TR_ID_LEN); |
1659 | 1665 | ||
1660 | ieee80211_tx_skb(sdata, skb, 1); | 1666 | ieee80211_tx_skb(sdata, skb, 1); |
1661 | } | 1667 | } |
1662 | 1668 | ||
1663 | static ieee80211_rx_result debug_noinline | 1669 | static ieee80211_rx_result debug_noinline |
1664 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | 1670 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) |
1665 | { | 1671 | { |
1666 | struct ieee80211_local *local = rx->local; | 1672 | struct ieee80211_local *local = rx->local; |
1667 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1673 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1668 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1674 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1669 | int len = rx->skb->len; | 1675 | int len = rx->skb->len; |
1670 | 1676 | ||
1671 | if (!ieee80211_is_action(mgmt->frame_control)) | 1677 | if (!ieee80211_is_action(mgmt->frame_control)) |
1672 | return RX_CONTINUE; | 1678 | return RX_CONTINUE; |
1673 | 1679 | ||
1674 | if (!rx->sta) | 1680 | if (!rx->sta) |
1675 | return RX_DROP_MONITOR; | 1681 | return RX_DROP_MONITOR; |
1676 | 1682 | ||
1677 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1683 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
1678 | return RX_DROP_MONITOR; | 1684 | return RX_DROP_MONITOR; |
1679 | 1685 | ||
1680 | if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) | 1686 | if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) |
1681 | return RX_DROP_MONITOR; | 1687 | return RX_DROP_MONITOR; |
1682 | 1688 | ||
1683 | /* all categories we currently handle have action_code */ | 1689 | /* all categories we currently handle have action_code */ |
1684 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1690 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1685 | return RX_DROP_MONITOR; | 1691 | return RX_DROP_MONITOR; |
1686 | 1692 | ||
1687 | switch (mgmt->u.action.category) { | 1693 | switch (mgmt->u.action.category) { |
1688 | case WLAN_CATEGORY_BACK: | 1694 | case WLAN_CATEGORY_BACK: |
1689 | /* | 1695 | /* |
1690 | * The aggregation code is not prepared to handle | 1696 | * The aggregation code is not prepared to handle |
1691 | * anything but STA/AP due to the BSSID handling; | 1697 | * anything but STA/AP due to the BSSID handling; |
1692 | * IBSS could work in the code but isn't supported | 1698 | * IBSS could work in the code but isn't supported |
1693 | * by drivers or the standard. | 1699 | * by drivers or the standard. |
1694 | */ | 1700 | */ |
1695 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 1701 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
1696 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1702 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1697 | sdata->vif.type != NL80211_IFTYPE_AP) | 1703 | sdata->vif.type != NL80211_IFTYPE_AP) |
1698 | return RX_DROP_MONITOR; | 1704 | return RX_DROP_MONITOR; |
1699 | 1705 | ||
1700 | switch (mgmt->u.action.u.addba_req.action_code) { | 1706 | switch (mgmt->u.action.u.addba_req.action_code) { |
1701 | case WLAN_ACTION_ADDBA_REQ: | 1707 | case WLAN_ACTION_ADDBA_REQ: |
1702 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1708 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1703 | sizeof(mgmt->u.action.u.addba_req))) | 1709 | sizeof(mgmt->u.action.u.addba_req))) |
1704 | return RX_DROP_MONITOR; | 1710 | return RX_DROP_MONITOR; |
1705 | ieee80211_process_addba_request(local, rx->sta, mgmt, len); | 1711 | ieee80211_process_addba_request(local, rx->sta, mgmt, len); |
1706 | break; | 1712 | break; |
1707 | case WLAN_ACTION_ADDBA_RESP: | 1713 | case WLAN_ACTION_ADDBA_RESP: |
1708 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1714 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1709 | sizeof(mgmt->u.action.u.addba_resp))) | 1715 | sizeof(mgmt->u.action.u.addba_resp))) |
1710 | return RX_DROP_MONITOR; | 1716 | return RX_DROP_MONITOR; |
1711 | ieee80211_process_addba_resp(local, rx->sta, mgmt, len); | 1717 | ieee80211_process_addba_resp(local, rx->sta, mgmt, len); |
1712 | break; | 1718 | break; |
1713 | case WLAN_ACTION_DELBA: | 1719 | case WLAN_ACTION_DELBA: |
1714 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1720 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1715 | sizeof(mgmt->u.action.u.delba))) | 1721 | sizeof(mgmt->u.action.u.delba))) |
1716 | return RX_DROP_MONITOR; | 1722 | return RX_DROP_MONITOR; |
1717 | ieee80211_process_delba(sdata, rx->sta, mgmt, len); | 1723 | ieee80211_process_delba(sdata, rx->sta, mgmt, len); |
1718 | break; | 1724 | break; |
1719 | } | 1725 | } |
1720 | break; | 1726 | break; |
1721 | case WLAN_CATEGORY_SPECTRUM_MGMT: | 1727 | case WLAN_CATEGORY_SPECTRUM_MGMT: |
1722 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) | 1728 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) |
1723 | return RX_DROP_MONITOR; | 1729 | return RX_DROP_MONITOR; |
1724 | 1730 | ||
1725 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1731 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
1726 | return RX_DROP_MONITOR; | 1732 | return RX_DROP_MONITOR; |
1727 | 1733 | ||
1728 | switch (mgmt->u.action.u.measurement.action_code) { | 1734 | switch (mgmt->u.action.u.measurement.action_code) { |
1729 | case WLAN_ACTION_SPCT_MSR_REQ: | 1735 | case WLAN_ACTION_SPCT_MSR_REQ: |
1730 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1736 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1731 | sizeof(mgmt->u.action.u.measurement))) | 1737 | sizeof(mgmt->u.action.u.measurement))) |
1732 | return RX_DROP_MONITOR; | 1738 | return RX_DROP_MONITOR; |
1733 | ieee80211_process_measurement_req(sdata, mgmt, len); | 1739 | ieee80211_process_measurement_req(sdata, mgmt, len); |
1734 | break; | 1740 | break; |
1735 | case WLAN_ACTION_SPCT_CHL_SWITCH: | 1741 | case WLAN_ACTION_SPCT_CHL_SWITCH: |
1736 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1742 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1737 | sizeof(mgmt->u.action.u.chan_switch))) | 1743 | sizeof(mgmt->u.action.u.chan_switch))) |
1738 | return RX_DROP_MONITOR; | 1744 | return RX_DROP_MONITOR; |
1739 | 1745 | ||
1740 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1746 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
1741 | return RX_DROP_MONITOR; | 1747 | return RX_DROP_MONITOR; |
1742 | 1748 | ||
1743 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) | 1749 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) |
1744 | return RX_DROP_MONITOR; | 1750 | return RX_DROP_MONITOR; |
1745 | 1751 | ||
1746 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 1752 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); |
1747 | } | 1753 | } |
1748 | break; | 1754 | break; |
1749 | case WLAN_CATEGORY_SA_QUERY: | 1755 | case WLAN_CATEGORY_SA_QUERY: |
1750 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1756 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
1751 | sizeof(mgmt->u.action.u.sa_query))) | 1757 | sizeof(mgmt->u.action.u.sa_query))) |
1752 | return RX_DROP_MONITOR; | 1758 | return RX_DROP_MONITOR; |
1753 | switch (mgmt->u.action.u.sa_query.action) { | 1759 | switch (mgmt->u.action.u.sa_query.action) { |
1754 | case WLAN_ACTION_SA_QUERY_REQUEST: | 1760 | case WLAN_ACTION_SA_QUERY_REQUEST: |
1755 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1761 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
1756 | return RX_DROP_MONITOR; | 1762 | return RX_DROP_MONITOR; |
1757 | ieee80211_process_sa_query_req(sdata, mgmt, len); | 1763 | ieee80211_process_sa_query_req(sdata, mgmt, len); |
1758 | break; | 1764 | break; |
1759 | case WLAN_ACTION_SA_QUERY_RESPONSE: | 1765 | case WLAN_ACTION_SA_QUERY_RESPONSE: |
1760 | /* | 1766 | /* |
1761 | * SA Query response is currently only used in AP mode | 1767 | * SA Query response is currently only used in AP mode |
1762 | * and it is processed in user space. | 1768 | * and it is processed in user space. |
1763 | */ | 1769 | */ |
1764 | return RX_CONTINUE; | 1770 | return RX_CONTINUE; |
1765 | } | 1771 | } |
1766 | break; | 1772 | break; |
1767 | default: | 1773 | default: |
1768 | return RX_CONTINUE; | 1774 | return RX_CONTINUE; |
1769 | } | 1775 | } |
1770 | 1776 | ||
1771 | rx->sta->rx_packets++; | 1777 | rx->sta->rx_packets++; |
1772 | dev_kfree_skb(rx->skb); | 1778 | dev_kfree_skb(rx->skb); |
1773 | return RX_QUEUED; | 1779 | return RX_QUEUED; |
1774 | } | 1780 | } |
1775 | 1781 | ||
1776 | static ieee80211_rx_result debug_noinline | 1782 | static ieee80211_rx_result debug_noinline |
1777 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1783 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
1778 | { | 1784 | { |
1779 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1785 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1780 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1786 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1781 | 1787 | ||
1782 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1788 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
1783 | return RX_DROP_MONITOR; | 1789 | return RX_DROP_MONITOR; |
1784 | 1790 | ||
1785 | if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) | 1791 | if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) |
1786 | return RX_DROP_MONITOR; | 1792 | return RX_DROP_MONITOR; |
1787 | 1793 | ||
1788 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1794 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
1789 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | 1795 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); |
1790 | 1796 | ||
1791 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 1797 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
1792 | return ieee80211_ibss_rx_mgmt(sdata, rx->skb); | 1798 | return ieee80211_ibss_rx_mgmt(sdata, rx->skb); |
1793 | 1799 | ||
1794 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 1800 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
1795 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 1801 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); |
1796 | 1802 | ||
1797 | return RX_DROP_MONITOR; | 1803 | return RX_DROP_MONITOR; |
1798 | } | 1804 | } |
1799 | 1805 | ||
1800 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | 1806 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, |
1801 | struct ieee80211_rx_data *rx) | 1807 | struct ieee80211_rx_data *rx) |
1802 | { | 1808 | { |
1803 | int keyidx; | 1809 | int keyidx; |
1804 | unsigned int hdrlen; | 1810 | unsigned int hdrlen; |
1805 | 1811 | ||
1806 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1812 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1807 | if (rx->skb->len >= hdrlen + 4) | 1813 | if (rx->skb->len >= hdrlen + 4) |
1808 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | 1814 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
1809 | else | 1815 | else |
1810 | keyidx = -1; | 1816 | keyidx = -1; |
1811 | 1817 | ||
1812 | if (!rx->sta) { | 1818 | if (!rx->sta) { |
1813 | /* | 1819 | /* |
1814 | * Some hardware seem to generate incorrect Michael MIC | 1820 | * Some hardware seem to generate incorrect Michael MIC |
1815 | * reports; ignore them to avoid triggering countermeasures. | 1821 | * reports; ignore them to avoid triggering countermeasures. |
1816 | */ | 1822 | */ |
1817 | return; | 1823 | return; |
1818 | } | 1824 | } |
1819 | 1825 | ||
1820 | if (!ieee80211_has_protected(hdr->frame_control)) | 1826 | if (!ieee80211_has_protected(hdr->frame_control)) |
1821 | return; | 1827 | return; |
1822 | 1828 | ||
1823 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { | 1829 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { |
1824 | /* | 1830 | /* |
1825 | * APs with pairwise keys should never receive Michael MIC | 1831 | * APs with pairwise keys should never receive Michael MIC |
1826 | * errors for non-zero keyidx because these are reserved for | 1832 | * errors for non-zero keyidx because these are reserved for |
1827 | * group keys and only the AP is sending real multicast | 1833 | * group keys and only the AP is sending real multicast |
1828 | * frames in the BSS. | 1834 | * frames in the BSS. |
1829 | */ | 1835 | */ |
1830 | return; | 1836 | return; |
1831 | } | 1837 | } |
1832 | 1838 | ||
1833 | if (!ieee80211_is_data(hdr->frame_control) && | 1839 | if (!ieee80211_is_data(hdr->frame_control) && |
1834 | !ieee80211_is_auth(hdr->frame_control)) | 1840 | !ieee80211_is_auth(hdr->frame_control)) |
1835 | return; | 1841 | return; |
1836 | 1842 | ||
1837 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, | 1843 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, |
1838 | GFP_ATOMIC); | 1844 | GFP_ATOMIC); |
1839 | } | 1845 | } |
1840 | 1846 | ||
1841 | /* TODO: use IEEE80211_RX_FRAGMENTED */ | 1847 | /* TODO: use IEEE80211_RX_FRAGMENTED */ |
1842 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | 1848 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) |
1843 | { | 1849 | { |
1844 | struct ieee80211_sub_if_data *sdata; | 1850 | struct ieee80211_sub_if_data *sdata; |
1845 | struct ieee80211_local *local = rx->local; | 1851 | struct ieee80211_local *local = rx->local; |
1846 | struct ieee80211_rtap_hdr { | 1852 | struct ieee80211_rtap_hdr { |
1847 | struct ieee80211_radiotap_header hdr; | 1853 | struct ieee80211_radiotap_header hdr; |
1848 | u8 flags; | 1854 | u8 flags; |
1849 | u8 rate; | 1855 | u8 rate; |
1850 | __le16 chan_freq; | 1856 | __le16 chan_freq; |
1851 | __le16 chan_flags; | 1857 | __le16 chan_flags; |
1852 | } __attribute__ ((packed)) *rthdr; | 1858 | } __attribute__ ((packed)) *rthdr; |
1853 | struct sk_buff *skb = rx->skb, *skb2; | 1859 | struct sk_buff *skb = rx->skb, *skb2; |
1854 | struct net_device *prev_dev = NULL; | 1860 | struct net_device *prev_dev = NULL; |
1855 | struct ieee80211_rx_status *status = rx->status; | 1861 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
1856 | 1862 | ||
1857 | if (rx->flags & IEEE80211_RX_CMNTR_REPORTED) | 1863 | if (rx->flags & IEEE80211_RX_CMNTR_REPORTED) |
1858 | goto out_free_skb; | 1864 | goto out_free_skb; |
1859 | 1865 | ||
1860 | if (skb_headroom(skb) < sizeof(*rthdr) && | 1866 | if (skb_headroom(skb) < sizeof(*rthdr) && |
1861 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 1867 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
1862 | goto out_free_skb; | 1868 | goto out_free_skb; |
1863 | 1869 | ||
1864 | rthdr = (void *)skb_push(skb, sizeof(*rthdr)); | 1870 | rthdr = (void *)skb_push(skb, sizeof(*rthdr)); |
1865 | memset(rthdr, 0, sizeof(*rthdr)); | 1871 | memset(rthdr, 0, sizeof(*rthdr)); |
1866 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 1872 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
1867 | rthdr->hdr.it_present = | 1873 | rthdr->hdr.it_present = |
1868 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 1874 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
1869 | (1 << IEEE80211_RADIOTAP_RATE) | | 1875 | (1 << IEEE80211_RADIOTAP_RATE) | |
1870 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 1876 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
1871 | 1877 | ||
1872 | rthdr->rate = rx->rate->bitrate / 5; | 1878 | rthdr->rate = rx->rate->bitrate / 5; |
1873 | rthdr->chan_freq = cpu_to_le16(status->freq); | 1879 | rthdr->chan_freq = cpu_to_le16(status->freq); |
1874 | 1880 | ||
1875 | if (status->band == IEEE80211_BAND_5GHZ) | 1881 | if (status->band == IEEE80211_BAND_5GHZ) |
1876 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | | 1882 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | |
1877 | IEEE80211_CHAN_5GHZ); | 1883 | IEEE80211_CHAN_5GHZ); |
1878 | else | 1884 | else |
1879 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | | 1885 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | |
1880 | IEEE80211_CHAN_2GHZ); | 1886 | IEEE80211_CHAN_2GHZ); |
1881 | 1887 | ||
1882 | skb_set_mac_header(skb, 0); | 1888 | skb_set_mac_header(skb, 0); |
1883 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1889 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1884 | skb->pkt_type = PACKET_OTHERHOST; | 1890 | skb->pkt_type = PACKET_OTHERHOST; |
1885 | skb->protocol = htons(ETH_P_802_2); | 1891 | skb->protocol = htons(ETH_P_802_2); |
1886 | 1892 | ||
1887 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 1893 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
1888 | if (!netif_running(sdata->dev)) | 1894 | if (!netif_running(sdata->dev)) |
1889 | continue; | 1895 | continue; |
1890 | 1896 | ||
1891 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || | 1897 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || |
1892 | !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) | 1898 | !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) |
1893 | continue; | 1899 | continue; |
1894 | 1900 | ||
1895 | if (prev_dev) { | 1901 | if (prev_dev) { |
1896 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1902 | skb2 = skb_clone(skb, GFP_ATOMIC); |
1897 | if (skb2) { | 1903 | if (skb2) { |
1898 | skb2->dev = prev_dev; | 1904 | skb2->dev = prev_dev; |
1899 | netif_rx(skb2); | 1905 | netif_rx(skb2); |
1900 | } | 1906 | } |
1901 | } | 1907 | } |
1902 | 1908 | ||
1903 | prev_dev = sdata->dev; | 1909 | prev_dev = sdata->dev; |
1904 | sdata->dev->stats.rx_packets++; | 1910 | sdata->dev->stats.rx_packets++; |
1905 | sdata->dev->stats.rx_bytes += skb->len; | 1911 | sdata->dev->stats.rx_bytes += skb->len; |
1906 | } | 1912 | } |
1907 | 1913 | ||
1908 | if (prev_dev) { | 1914 | if (prev_dev) { |
1909 | skb->dev = prev_dev; | 1915 | skb->dev = prev_dev; |
1910 | netif_rx(skb); | 1916 | netif_rx(skb); |
1911 | skb = NULL; | 1917 | skb = NULL; |
1912 | } else | 1918 | } else |
1913 | goto out_free_skb; | 1919 | goto out_free_skb; |
1914 | 1920 | ||
1915 | rx->flags |= IEEE80211_RX_CMNTR_REPORTED; | 1921 | rx->flags |= IEEE80211_RX_CMNTR_REPORTED; |
1916 | return; | 1922 | return; |
1917 | 1923 | ||
1918 | out_free_skb: | 1924 | out_free_skb: |
1919 | dev_kfree_skb(skb); | 1925 | dev_kfree_skb(skb); |
1920 | } | 1926 | } |
1921 | 1927 | ||
1922 | 1928 | ||
1923 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1929 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
1924 | struct ieee80211_rx_data *rx, | 1930 | struct ieee80211_rx_data *rx, |
1925 | struct sk_buff *skb) | 1931 | struct sk_buff *skb) |
1926 | { | 1932 | { |
1927 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1933 | ieee80211_rx_result res = RX_DROP_MONITOR; |
1928 | 1934 | ||
1929 | rx->skb = skb; | 1935 | rx->skb = skb; |
1930 | rx->sdata = sdata; | 1936 | rx->sdata = sdata; |
1931 | rx->dev = sdata->dev; | ||
1932 | 1937 | ||
1933 | #define CALL_RXH(rxh) \ | 1938 | #define CALL_RXH(rxh) \ |
1934 | do { \ | 1939 | do { \ |
1935 | res = rxh(rx); \ | 1940 | res = rxh(rx); \ |
1936 | if (res != RX_CONTINUE) \ | 1941 | if (res != RX_CONTINUE) \ |
1937 | goto rxh_done; \ | 1942 | goto rxh_done; \ |
1938 | } while (0); | 1943 | } while (0); |
1939 | 1944 | ||
1940 | CALL_RXH(ieee80211_rx_h_passive_scan) | 1945 | CALL_RXH(ieee80211_rx_h_passive_scan) |
1941 | CALL_RXH(ieee80211_rx_h_check) | 1946 | CALL_RXH(ieee80211_rx_h_check) |
1942 | CALL_RXH(ieee80211_rx_h_decrypt) | 1947 | CALL_RXH(ieee80211_rx_h_decrypt) |
1943 | CALL_RXH(ieee80211_rx_h_check_more_data) | 1948 | CALL_RXH(ieee80211_rx_h_check_more_data) |
1944 | CALL_RXH(ieee80211_rx_h_sta_process) | 1949 | CALL_RXH(ieee80211_rx_h_sta_process) |
1945 | CALL_RXH(ieee80211_rx_h_defragment) | 1950 | CALL_RXH(ieee80211_rx_h_defragment) |
1946 | CALL_RXH(ieee80211_rx_h_ps_poll) | 1951 | CALL_RXH(ieee80211_rx_h_ps_poll) |
1947 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) | 1952 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
1948 | /* must be after MMIC verify so header is counted in MPDU mic */ | 1953 | /* must be after MMIC verify so header is counted in MPDU mic */ |
1949 | CALL_RXH(ieee80211_rx_h_remove_qos_control) | 1954 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
1950 | CALL_RXH(ieee80211_rx_h_amsdu) | 1955 | CALL_RXH(ieee80211_rx_h_amsdu) |
1951 | #ifdef CONFIG_MAC80211_MESH | 1956 | #ifdef CONFIG_MAC80211_MESH |
1952 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1957 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
1953 | CALL_RXH(ieee80211_rx_h_mesh_fwding); | 1958 | CALL_RXH(ieee80211_rx_h_mesh_fwding); |
1954 | #endif | 1959 | #endif |
1955 | CALL_RXH(ieee80211_rx_h_data) | 1960 | CALL_RXH(ieee80211_rx_h_data) |
1956 | CALL_RXH(ieee80211_rx_h_ctrl) | 1961 | CALL_RXH(ieee80211_rx_h_ctrl) |
1957 | CALL_RXH(ieee80211_rx_h_action) | 1962 | CALL_RXH(ieee80211_rx_h_action) |
1958 | CALL_RXH(ieee80211_rx_h_mgmt) | 1963 | CALL_RXH(ieee80211_rx_h_mgmt) |
1959 | 1964 | ||
1960 | #undef CALL_RXH | 1965 | #undef CALL_RXH |
1961 | 1966 | ||
1962 | rxh_done: | 1967 | rxh_done: |
1963 | switch (res) { | 1968 | switch (res) { |
1964 | case RX_DROP_MONITOR: | 1969 | case RX_DROP_MONITOR: |
1965 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1970 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); |
1966 | if (rx->sta) | 1971 | if (rx->sta) |
1967 | rx->sta->rx_dropped++; | 1972 | rx->sta->rx_dropped++; |
1968 | /* fall through */ | 1973 | /* fall through */ |
1969 | case RX_CONTINUE: | 1974 | case RX_CONTINUE: |
1970 | ieee80211_rx_cooked_monitor(rx); | 1975 | ieee80211_rx_cooked_monitor(rx); |
1971 | break; | 1976 | break; |
1972 | case RX_DROP_UNUSABLE: | 1977 | case RX_DROP_UNUSABLE: |
1973 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1978 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); |
1974 | if (rx->sta) | 1979 | if (rx->sta) |
1975 | rx->sta->rx_dropped++; | 1980 | rx->sta->rx_dropped++; |
1976 | dev_kfree_skb(rx->skb); | 1981 | dev_kfree_skb(rx->skb); |
1977 | break; | 1982 | break; |
1978 | case RX_QUEUED: | 1983 | case RX_QUEUED: |
1979 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 1984 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); |
1980 | break; | 1985 | break; |
1981 | } | 1986 | } |
1982 | } | 1987 | } |
1983 | 1988 | ||
1984 | /* main receive path */ | 1989 | /* main receive path */ |
1985 | 1990 | ||
1986 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | 1991 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, |
1987 | struct ieee80211_rx_data *rx, | 1992 | struct ieee80211_rx_data *rx, |
1988 | struct ieee80211_hdr *hdr) | 1993 | struct ieee80211_hdr *hdr) |
1989 | { | 1994 | { |
1990 | u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, sdata->vif.type); | 1995 | struct sk_buff *skb = rx->skb; |
1996 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1997 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | ||
1991 | int multicast = is_multicast_ether_addr(hdr->addr1); | 1998 | int multicast = is_multicast_ether_addr(hdr->addr1); |
1992 | 1999 | ||
1993 | switch (sdata->vif.type) { | 2000 | switch (sdata->vif.type) { |
1994 | case NL80211_IFTYPE_STATION: | 2001 | case NL80211_IFTYPE_STATION: |
1995 | if (!bssid && !sdata->use_4addr) | 2002 | if (!bssid && !sdata->use_4addr) |
1996 | return 0; | 2003 | return 0; |
1997 | if (!multicast && | 2004 | if (!multicast && |
1998 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { | 2005 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { |
1999 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2006 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2000 | return 0; | 2007 | return 0; |
2001 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2008 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2002 | } | 2009 | } |
2003 | break; | 2010 | break; |
2004 | case NL80211_IFTYPE_ADHOC: | 2011 | case NL80211_IFTYPE_ADHOC: |
2005 | if (!bssid) | 2012 | if (!bssid) |
2006 | return 0; | 2013 | return 0; |
2007 | if (ieee80211_is_beacon(hdr->frame_control)) { | 2014 | if (ieee80211_is_beacon(hdr->frame_control)) { |
2008 | return 1; | 2015 | return 1; |
2009 | } | 2016 | } |
2010 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2017 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2011 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2018 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) |
2012 | return 0; | 2019 | return 0; |
2013 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2020 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2014 | } else if (!multicast && | 2021 | } else if (!multicast && |
2015 | compare_ether_addr(sdata->dev->dev_addr, | 2022 | compare_ether_addr(sdata->dev->dev_addr, |
2016 | hdr->addr1) != 0) { | 2023 | hdr->addr1) != 0) { |
2017 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2024 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2018 | return 0; | 2025 | return 0; |
2019 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2026 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2020 | } else if (!rx->sta) { | 2027 | } else if (!rx->sta) { |
2021 | int rate_idx; | 2028 | int rate_idx; |
2022 | if (rx->status->flag & RX_FLAG_HT) | 2029 | if (status->flag & RX_FLAG_HT) |
2023 | rate_idx = 0; /* TODO: HT rates */ | 2030 | rate_idx = 0; /* TODO: HT rates */ |
2024 | else | 2031 | else |
2025 | rate_idx = rx->status->rate_idx; | 2032 | rate_idx = status->rate_idx; |
2026 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, | 2033 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, |
2027 | BIT(rate_idx)); | 2034 | BIT(rate_idx)); |
2028 | } | 2035 | } |
2029 | break; | 2036 | break; |
2030 | case NL80211_IFTYPE_MESH_POINT: | 2037 | case NL80211_IFTYPE_MESH_POINT: |
2031 | if (!multicast && | 2038 | if (!multicast && |
2032 | compare_ether_addr(sdata->dev->dev_addr, | 2039 | compare_ether_addr(sdata->dev->dev_addr, |
2033 | hdr->addr1) != 0) { | 2040 | hdr->addr1) != 0) { |
2034 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2041 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2035 | return 0; | 2042 | return 0; |
2036 | 2043 | ||
2037 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2044 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2038 | } | 2045 | } |
2039 | break; | 2046 | break; |
2040 | case NL80211_IFTYPE_AP_VLAN: | 2047 | case NL80211_IFTYPE_AP_VLAN: |
2041 | case NL80211_IFTYPE_AP: | 2048 | case NL80211_IFTYPE_AP: |
2042 | if (!bssid) { | 2049 | if (!bssid) { |
2043 | if (compare_ether_addr(sdata->dev->dev_addr, | 2050 | if (compare_ether_addr(sdata->dev->dev_addr, |
2044 | hdr->addr1)) | 2051 | hdr->addr1)) |
2045 | return 0; | 2052 | return 0; |
2046 | } else if (!ieee80211_bssid_match(bssid, | 2053 | } else if (!ieee80211_bssid_match(bssid, |
2047 | sdata->dev->dev_addr)) { | 2054 | sdata->dev->dev_addr)) { |
2048 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2055 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) |
2049 | return 0; | 2056 | return 0; |
2050 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2057 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2051 | } | 2058 | } |
2052 | break; | 2059 | break; |
2053 | case NL80211_IFTYPE_WDS: | 2060 | case NL80211_IFTYPE_WDS: |
2054 | if (bssid || !ieee80211_is_data(hdr->frame_control)) | 2061 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
2055 | return 0; | 2062 | return 0; |
2056 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) | 2063 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) |
2057 | return 0; | 2064 | return 0; |
2058 | break; | 2065 | break; |
2059 | case NL80211_IFTYPE_MONITOR: | 2066 | case NL80211_IFTYPE_MONITOR: |
2060 | case NL80211_IFTYPE_UNSPECIFIED: | 2067 | case NL80211_IFTYPE_UNSPECIFIED: |
2061 | case __NL80211_IFTYPE_AFTER_LAST: | 2068 | case __NL80211_IFTYPE_AFTER_LAST: |
2062 | /* should never get here */ | 2069 | /* should never get here */ |
2063 | WARN_ON(1); | 2070 | WARN_ON(1); |
2064 | break; | 2071 | break; |
2065 | } | 2072 | } |
2066 | 2073 | ||
2067 | return 1; | 2074 | return 1; |
2068 | } | 2075 | } |
2069 | 2076 | ||
2070 | /* | 2077 | /* |
2071 | * This is the actual Rx frames handler. as it blongs to Rx path it must | 2078 | * This is the actual Rx frames handler. as it blongs to Rx path it must |
2072 | * be called with rcu_read_lock protection. | 2079 | * be called with rcu_read_lock protection. |
2073 | */ | 2080 | */ |
2074 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2081 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2075 | struct sk_buff *skb, | 2082 | struct sk_buff *skb, |
2076 | struct ieee80211_rate *rate) | 2083 | struct ieee80211_rate *rate) |
2077 | { | 2084 | { |
2078 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2085 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2079 | struct ieee80211_local *local = hw_to_local(hw); | 2086 | struct ieee80211_local *local = hw_to_local(hw); |
2080 | struct ieee80211_sub_if_data *sdata; | 2087 | struct ieee80211_sub_if_data *sdata; |
2081 | struct ieee80211_hdr *hdr; | 2088 | struct ieee80211_hdr *hdr; |
2082 | struct ieee80211_rx_data rx; | 2089 | struct ieee80211_rx_data rx; |
2083 | int prepares; | 2090 | int prepares; |
2084 | struct ieee80211_sub_if_data *prev = NULL; | 2091 | struct ieee80211_sub_if_data *prev = NULL; |
2085 | struct sk_buff *skb_new; | 2092 | struct sk_buff *skb_new; |
2086 | 2093 | ||
2087 | hdr = (struct ieee80211_hdr *)skb->data; | 2094 | hdr = (struct ieee80211_hdr *)skb->data; |
2088 | memset(&rx, 0, sizeof(rx)); | 2095 | memset(&rx, 0, sizeof(rx)); |
2089 | rx.skb = skb; | 2096 | rx.skb = skb; |
2090 | rx.local = local; | 2097 | rx.local = local; |
2091 | rx.status = status; | ||
2092 | rx.rate = rate; | 2098 | rx.rate = rate; |
2093 | 2099 | ||
2094 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) | 2100 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) |
2095 | local->dot11ReceivedFragmentCount++; | 2101 | local->dot11ReceivedFragmentCount++; |
2096 | 2102 | ||
2097 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2103 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2098 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2104 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2099 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2105 | rx.flags |= IEEE80211_RX_IN_SCAN; |
2100 | 2106 | ||
2101 | ieee80211_parse_qos(&rx); | 2107 | ieee80211_parse_qos(&rx); |
2102 | ieee80211_verify_alignment(&rx); | 2108 | ieee80211_verify_alignment(&rx); |
2103 | 2109 | ||
2104 | rx.sta = sta_info_get(local, hdr->addr2); | 2110 | rx.sta = sta_info_get(local, hdr->addr2); |
2105 | if (rx.sta) { | 2111 | if (rx.sta) |
2106 | rx.sdata = rx.sta->sdata; | 2112 | rx.sdata = rx.sta->sdata; |
2107 | rx.dev = rx.sta->sdata->dev; | ||
2108 | } | ||
2109 | 2113 | ||
2110 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { | 2114 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { |
2111 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2115 | rx.flags |= IEEE80211_RX_RA_MATCH; |
2112 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | 2116 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); |
2113 | if (prepares) { | 2117 | if (prepares) { |
2114 | if (status->flag & RX_FLAG_MMIC_ERROR) { | 2118 | if (status->flag & RX_FLAG_MMIC_ERROR) { |
2115 | if (rx.flags & IEEE80211_RX_RA_MATCH) | 2119 | if (rx.flags & IEEE80211_RX_RA_MATCH) |
2116 | ieee80211_rx_michael_mic_report(hdr, &rx); | 2120 | ieee80211_rx_michael_mic_report(hdr, &rx); |
2117 | } else | 2121 | } else |
2118 | prev = rx.sdata; | 2122 | prev = rx.sdata; |
2119 | } | 2123 | } |
2120 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 2124 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
2121 | if (!netif_running(sdata->dev)) | 2125 | if (!netif_running(sdata->dev)) |
2122 | continue; | 2126 | continue; |
2123 | 2127 | ||
2124 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | 2128 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
2125 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 2129 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
2126 | continue; | 2130 | continue; |
2127 | 2131 | ||
2128 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2132 | rx.flags |= IEEE80211_RX_RA_MATCH; |
2129 | prepares = prepare_for_handlers(sdata, &rx, hdr); | 2133 | prepares = prepare_for_handlers(sdata, &rx, hdr); |
2130 | 2134 | ||
2131 | if (!prepares) | 2135 | if (!prepares) |
2132 | continue; | 2136 | continue; |
2133 | 2137 | ||
2134 | if (status->flag & RX_FLAG_MMIC_ERROR) { | 2138 | if (status->flag & RX_FLAG_MMIC_ERROR) { |
2135 | rx.sdata = sdata; | 2139 | rx.sdata = sdata; |
2136 | if (rx.flags & IEEE80211_RX_RA_MATCH) | 2140 | if (rx.flags & IEEE80211_RX_RA_MATCH) |
2137 | ieee80211_rx_michael_mic_report(hdr, &rx); | 2141 | ieee80211_rx_michael_mic_report(hdr, &rx); |
2138 | continue; | 2142 | continue; |
2139 | } | 2143 | } |
2140 | 2144 | ||
2141 | /* | 2145 | /* |
2142 | * frame is destined for this interface, but if it's not | 2146 | * frame is destined for this interface, but if it's not |
2143 | * also for the previous one we handle that after the | 2147 | * also for the previous one we handle that after the |
2144 | * loop to avoid copying the SKB once too much | 2148 | * loop to avoid copying the SKB once too much |
2145 | */ | 2149 | */ |
2146 | 2150 | ||
2147 | if (!prev) { | 2151 | if (!prev) { |
2148 | prev = sdata; | 2152 | prev = sdata; |
2149 | continue; | 2153 | continue; |
2150 | } | 2154 | } |
2151 | 2155 | ||
2152 | /* | 2156 | /* |
2153 | * frame was destined for the previous interface | 2157 | * frame was destined for the previous interface |
2154 | * so invoke RX handlers for it | 2158 | * so invoke RX handlers for it |
2155 | */ | 2159 | */ |
2156 | 2160 | ||
2157 | skb_new = skb_copy(skb, GFP_ATOMIC); | 2161 | skb_new = skb_copy(skb, GFP_ATOMIC); |
2158 | if (!skb_new) { | 2162 | if (!skb_new) { |
2159 | if (net_ratelimit()) | 2163 | if (net_ratelimit()) |
2160 | printk(KERN_DEBUG "%s: failed to copy " | 2164 | printk(KERN_DEBUG "%s: failed to copy " |
2161 | "multicast frame for %s\n", | 2165 | "multicast frame for %s\n", |
2162 | wiphy_name(local->hw.wiphy), | 2166 | wiphy_name(local->hw.wiphy), |
2163 | prev->dev->name); | 2167 | prev->dev->name); |
2164 | continue; | 2168 | continue; |
2165 | } | 2169 | } |
2166 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); | 2170 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); |
2167 | prev = sdata; | 2171 | prev = sdata; |
2168 | } | 2172 | } |
2169 | if (prev) | 2173 | if (prev) |
2170 | ieee80211_invoke_rx_handlers(prev, &rx, skb); | 2174 | ieee80211_invoke_rx_handlers(prev, &rx, skb); |
2171 | else | 2175 | else |
2172 | dev_kfree_skb(skb); | 2176 | dev_kfree_skb(skb); |
2173 | } | 2177 | } |
2174 | 2178 | ||
2175 | #define SEQ_MODULO 0x1000 | 2179 | #define SEQ_MODULO 0x1000 |
2176 | #define SEQ_MASK 0xfff | 2180 | #define SEQ_MASK 0xfff |
2177 | 2181 | ||
2178 | static inline int seq_less(u16 sq1, u16 sq2) | 2182 | static inline int seq_less(u16 sq1, u16 sq2) |
2179 | { | 2183 | { |
2180 | return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); | 2184 | return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); |
2181 | } | 2185 | } |
2182 | 2186 | ||
2183 | static inline u16 seq_inc(u16 sq) | 2187 | static inline u16 seq_inc(u16 sq) |
2184 | { | 2188 | { |
2185 | return (sq + 1) & SEQ_MASK; | 2189 | return (sq + 1) & SEQ_MASK; |
2186 | } | 2190 | } |
2187 | 2191 | ||
2188 | static inline u16 seq_sub(u16 sq1, u16 sq2) | 2192 | static inline u16 seq_sub(u16 sq1, u16 sq2) |
2189 | { | 2193 | { |
2190 | return (sq1 - sq2) & SEQ_MASK; | 2194 | return (sq1 - sq2) & SEQ_MASK; |
2191 | } | 2195 | } |
2192 | 2196 | ||
2193 | 2197 | ||
2194 | static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | 2198 | static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, |
2195 | struct tid_ampdu_rx *tid_agg_rx, | 2199 | struct tid_ampdu_rx *tid_agg_rx, |
2196 | int index) | 2200 | int index) |
2197 | { | 2201 | { |
2198 | struct ieee80211_supported_band *sband; | 2202 | struct ieee80211_supported_band *sband; |
2199 | struct ieee80211_rate *rate; | 2203 | struct ieee80211_rate *rate; |
2200 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 2204 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
2201 | struct ieee80211_rx_status *status; | 2205 | struct ieee80211_rx_status *status; |
2202 | 2206 | ||
2203 | if (!skb) | 2207 | if (!skb) |
2204 | goto no_frame; | 2208 | goto no_frame; |
2205 | 2209 | ||
2206 | status = IEEE80211_SKB_RXCB(skb); | 2210 | status = IEEE80211_SKB_RXCB(skb); |
2207 | 2211 | ||
2208 | /* release the reordered frames to stack */ | 2212 | /* release the reordered frames to stack */ |
2209 | sband = hw->wiphy->bands[status->band]; | 2213 | sband = hw->wiphy->bands[status->band]; |
2210 | if (status->flag & RX_FLAG_HT) | 2214 | if (status->flag & RX_FLAG_HT) |
2211 | rate = sband->bitrates; /* TODO: HT rates */ | 2215 | rate = sband->bitrates; /* TODO: HT rates */ |
2212 | else | 2216 | else |
2213 | rate = &sband->bitrates[status->rate_idx]; | 2217 | rate = &sband->bitrates[status->rate_idx]; |
2214 | __ieee80211_rx_handle_packet(hw, skb, rate); | 2218 | __ieee80211_rx_handle_packet(hw, skb, rate); |
2215 | tid_agg_rx->stored_mpdu_num--; | 2219 | tid_agg_rx->stored_mpdu_num--; |
2216 | tid_agg_rx->reorder_buf[index] = NULL; | 2220 | tid_agg_rx->reorder_buf[index] = NULL; |
2217 | 2221 | ||
2218 | no_frame: | 2222 | no_frame: |
2219 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 2223 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
2220 | } | 2224 | } |
2221 | 2225 | ||
2222 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | 2226 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, |
2223 | struct tid_ampdu_rx *tid_agg_rx, | 2227 | struct tid_ampdu_rx *tid_agg_rx, |
2224 | u16 head_seq_num) | 2228 | u16 head_seq_num) |
2225 | { | 2229 | { |
2226 | int index; | 2230 | int index; |
2227 | 2231 | ||
2228 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | 2232 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { |
2229 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 2233 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
2230 | tid_agg_rx->buf_size; | 2234 | tid_agg_rx->buf_size; |
2231 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 2235 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); |
2232 | } | 2236 | } |
2233 | } | 2237 | } |
2234 | 2238 | ||
2235 | /* | 2239 | /* |
2236 | * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If | 2240 | * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If |
2237 | * the skb was added to the buffer longer than this time ago, the earlier | 2241 | * the skb was added to the buffer longer than this time ago, the earlier |
2238 | * frames that have not yet been received are assumed to be lost and the skb | 2242 | * frames that have not yet been received are assumed to be lost and the skb |
2239 | * can be released for processing. This may also release other skb's from the | 2243 | * can be released for processing. This may also release other skb's from the |
2240 | * reorder buffer if there are no additional gaps between the frames. | 2244 | * reorder buffer if there are no additional gaps between the frames. |
2241 | */ | 2245 | */ |
2242 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 2246 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
2243 | 2247 | ||
2244 | /* | 2248 | /* |
2245 | * As this function belongs to the RX path it must be under | 2249 | * As this function belongs to the RX path it must be under |
2246 | * rcu_read_lock protection. It returns false if the frame | 2250 | * rcu_read_lock protection. It returns false if the frame |
2247 | * can be processed immediately, true if it was consumed. | 2251 | * can be processed immediately, true if it was consumed. |
2248 | */ | 2252 | */ |
2249 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2253 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2250 | struct tid_ampdu_rx *tid_agg_rx, | 2254 | struct tid_ampdu_rx *tid_agg_rx, |
2251 | struct sk_buff *skb) | 2255 | struct sk_buff *skb) |
2252 | { | 2256 | { |
2253 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2257 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2254 | u16 sc = le16_to_cpu(hdr->seq_ctrl); | 2258 | u16 sc = le16_to_cpu(hdr->seq_ctrl); |
2255 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | 2259 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; |
2256 | u16 head_seq_num, buf_size; | 2260 | u16 head_seq_num, buf_size; |
2257 | int index; | 2261 | int index; |
2258 | 2262 | ||
2259 | buf_size = tid_agg_rx->buf_size; | 2263 | buf_size = tid_agg_rx->buf_size; |
2260 | head_seq_num = tid_agg_rx->head_seq_num; | 2264 | head_seq_num = tid_agg_rx->head_seq_num; |
2261 | 2265 | ||
2262 | /* frame with out of date sequence number */ | 2266 | /* frame with out of date sequence number */ |
2263 | if (seq_less(mpdu_seq_num, head_seq_num)) { | 2267 | if (seq_less(mpdu_seq_num, head_seq_num)) { |
2264 | dev_kfree_skb(skb); | 2268 | dev_kfree_skb(skb); |
2265 | return true; | 2269 | return true; |
2266 | } | 2270 | } |
2267 | 2271 | ||
2268 | /* | 2272 | /* |
2269 | * If frame the sequence number exceeds our buffering window | 2273 | * If frame the sequence number exceeds our buffering window |
2270 | * size release some previous frames to make room for this one. | 2274 | * size release some previous frames to make room for this one. |
2271 | */ | 2275 | */ |
2272 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { | 2276 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { |
2273 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); | 2277 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); |
2274 | /* release stored frames up to new head to stack */ | 2278 | /* release stored frames up to new head to stack */ |
2275 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); | 2279 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); |
2276 | } | 2280 | } |
2277 | 2281 | ||
2278 | /* Now the new frame is always in the range of the reordering buffer */ | 2282 | /* Now the new frame is always in the range of the reordering buffer */ |
2279 | 2283 | ||
2280 | index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; | 2284 | index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; |
2281 | 2285 | ||
2282 | /* check if we already stored this frame */ | 2286 | /* check if we already stored this frame */ |
2283 | if (tid_agg_rx->reorder_buf[index]) { | 2287 | if (tid_agg_rx->reorder_buf[index]) { |
2284 | dev_kfree_skb(skb); | 2288 | dev_kfree_skb(skb); |
2285 | return true; | 2289 | return true; |
2286 | } | 2290 | } |
2287 | 2291 | ||
2288 | /* | 2292 | /* |
2289 | * If the current MPDU is in the right order and nothing else | 2293 | * If the current MPDU is in the right order and nothing else |
2290 | * is stored we can process it directly, no need to buffer it. | 2294 | * is stored we can process it directly, no need to buffer it. |
2291 | */ | 2295 | */ |
2292 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && | 2296 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && |
2293 | tid_agg_rx->stored_mpdu_num == 0) { | 2297 | tid_agg_rx->stored_mpdu_num == 0) { |
2294 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 2298 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
2295 | return false; | 2299 | return false; |
2296 | } | 2300 | } |
2297 | 2301 | ||
2298 | /* put the frame in the reordering buffer */ | 2302 | /* put the frame in the reordering buffer */ |
2299 | tid_agg_rx->reorder_buf[index] = skb; | 2303 | tid_agg_rx->reorder_buf[index] = skb; |
2300 | tid_agg_rx->reorder_time[index] = jiffies; | 2304 | tid_agg_rx->reorder_time[index] = jiffies; |
2301 | tid_agg_rx->stored_mpdu_num++; | 2305 | tid_agg_rx->stored_mpdu_num++; |
2302 | /* release the buffer until next missing frame */ | 2306 | /* release the buffer until next missing frame */ |
2303 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 2307 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
2304 | tid_agg_rx->buf_size; | 2308 | tid_agg_rx->buf_size; |
2305 | if (!tid_agg_rx->reorder_buf[index] && | 2309 | if (!tid_agg_rx->reorder_buf[index] && |
2306 | tid_agg_rx->stored_mpdu_num > 1) { | 2310 | tid_agg_rx->stored_mpdu_num > 1) { |
2307 | /* | 2311 | /* |
2308 | * No buffers ready to be released, but check whether any | 2312 | * No buffers ready to be released, but check whether any |
2309 | * frames in the reorder buffer have timed out. | 2313 | * frames in the reorder buffer have timed out. |
2310 | */ | 2314 | */ |
2311 | int j; | 2315 | int j; |
2312 | int skipped = 1; | 2316 | int skipped = 1; |
2313 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | 2317 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; |
2314 | j = (j + 1) % tid_agg_rx->buf_size) { | 2318 | j = (j + 1) % tid_agg_rx->buf_size) { |
2315 | if (!tid_agg_rx->reorder_buf[j]) { | 2319 | if (!tid_agg_rx->reorder_buf[j]) { |
2316 | skipped++; | 2320 | skipped++; |
2317 | continue; | 2321 | continue; |
2318 | } | 2322 | } |
2319 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | 2323 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + |
2320 | HT_RX_REORDER_BUF_TIMEOUT)) | 2324 | HT_RX_REORDER_BUF_TIMEOUT)) |
2321 | break; | 2325 | break; |
2322 | 2326 | ||
2323 | #ifdef CONFIG_MAC80211_HT_DEBUG | 2327 | #ifdef CONFIG_MAC80211_HT_DEBUG |
2324 | if (net_ratelimit()) | 2328 | if (net_ratelimit()) |
2325 | printk(KERN_DEBUG "%s: release an RX reorder " | 2329 | printk(KERN_DEBUG "%s: release an RX reorder " |
2326 | "frame due to timeout on earlier " | 2330 | "frame due to timeout on earlier " |
2327 | "frames\n", | 2331 | "frames\n", |
2328 | wiphy_name(hw->wiphy)); | 2332 | wiphy_name(hw->wiphy)); |
2329 | #endif | 2333 | #endif |
2330 | ieee80211_release_reorder_frame(hw, tid_agg_rx, j); | 2334 | ieee80211_release_reorder_frame(hw, tid_agg_rx, j); |
2331 | 2335 | ||
2332 | /* | 2336 | /* |
2333 | * Increment the head seq# also for the skipped slots. | 2337 | * Increment the head seq# also for the skipped slots. |
2334 | */ | 2338 | */ |
2335 | tid_agg_rx->head_seq_num = | 2339 | tid_agg_rx->head_seq_num = |
2336 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; | 2340 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; |
2337 | skipped = 0; | 2341 | skipped = 0; |
2338 | } | 2342 | } |
2339 | } else while (tid_agg_rx->reorder_buf[index]) { | 2343 | } else while (tid_agg_rx->reorder_buf[index]) { |
2340 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 2344 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); |
2341 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 2345 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
2342 | tid_agg_rx->buf_size; | 2346 | tid_agg_rx->buf_size; |
2343 | } | 2347 | } |
2344 | 2348 | ||
2345 | return true; | 2349 | return true; |
2346 | } | 2350 | } |
2347 | 2351 | ||
2348 | /* | 2352 | /* |
2349 | * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns | 2353 | * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns |
2350 | * true if the MPDU was buffered, false if it should be processed. | 2354 | * true if the MPDU was buffered, false if it should be processed. |
2351 | */ | 2355 | */ |
2352 | static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | 2356 | static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, |
2353 | struct sk_buff *skb) | 2357 | struct sk_buff *skb) |
2354 | { | 2358 | { |
2355 | struct ieee80211_hw *hw = &local->hw; | 2359 | struct ieee80211_hw *hw = &local->hw; |
2356 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2360 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2357 | struct sta_info *sta; | 2361 | struct sta_info *sta; |
2358 | struct tid_ampdu_rx *tid_agg_rx; | 2362 | struct tid_ampdu_rx *tid_agg_rx; |
2359 | u16 sc; | 2363 | u16 sc; |
2360 | int tid; | 2364 | int tid; |
2361 | 2365 | ||
2362 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 2366 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
2363 | return false; | 2367 | return false; |
2364 | 2368 | ||
2365 | /* | 2369 | /* |
2366 | * filter the QoS data rx stream according to | 2370 | * filter the QoS data rx stream according to |
2367 | * STA/TID and check if this STA/TID is on aggregation | 2371 | * STA/TID and check if this STA/TID is on aggregation |
2368 | */ | 2372 | */ |
2369 | 2373 | ||
2370 | sta = sta_info_get(local, hdr->addr2); | 2374 | sta = sta_info_get(local, hdr->addr2); |
2371 | if (!sta) | 2375 | if (!sta) |
2372 | return false; | 2376 | return false; |
2373 | 2377 | ||
2374 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 2378 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
2375 | 2379 | ||
2376 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) | 2380 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) |
2377 | return false; | 2381 | return false; |
2378 | 2382 | ||
2379 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 2383 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
2380 | 2384 | ||
2381 | /* qos null data frames are excluded */ | 2385 | /* qos null data frames are excluded */ |
2382 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) | 2386 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
2383 | return false; | 2387 | return false; |
2384 | 2388 | ||
2385 | /* new, potentially un-ordered, ampdu frame - process it */ | 2389 | /* new, potentially un-ordered, ampdu frame - process it */ |
2386 | 2390 | ||
2387 | /* reset session timer */ | 2391 | /* reset session timer */ |
2388 | if (tid_agg_rx->timeout) | 2392 | if (tid_agg_rx->timeout) |
2389 | mod_timer(&tid_agg_rx->session_timer, | 2393 | mod_timer(&tid_agg_rx->session_timer, |
2390 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); | 2394 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); |
2391 | 2395 | ||
2392 | /* if this mpdu is fragmented - terminate rx aggregation session */ | 2396 | /* if this mpdu is fragmented - terminate rx aggregation session */ |
2393 | sc = le16_to_cpu(hdr->seq_ctrl); | 2397 | sc = le16_to_cpu(hdr->seq_ctrl); |
2394 | if (sc & IEEE80211_SCTL_FRAG) { | 2398 | if (sc & IEEE80211_SCTL_FRAG) { |
2395 | ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, | 2399 | ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, |
2396 | tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); | 2400 | tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); |
2397 | dev_kfree_skb(skb); | 2401 | dev_kfree_skb(skb); |
2398 | return true; | 2402 | return true; |
2399 | } | 2403 | } |
2400 | 2404 | ||
2401 | return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb); | 2405 | return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb); |
2402 | } | 2406 | } |
2403 | 2407 | ||
2404 | /* | 2408 | /* |
2405 | * This is the receive path handler. It is called by a low level driver when an | 2409 | * This is the receive path handler. It is called by a low level driver when an |
2406 | * 802.11 MPDU is received from the hardware. | 2410 | * 802.11 MPDU is received from the hardware. |
2407 | */ | 2411 | */ |
2408 | void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | 2412 | void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) |
2409 | { | 2413 | { |
2410 | struct ieee80211_local *local = hw_to_local(hw); | 2414 | struct ieee80211_local *local = hw_to_local(hw); |
2411 | struct ieee80211_rate *rate = NULL; | 2415 | struct ieee80211_rate *rate = NULL; |
2412 | struct ieee80211_supported_band *sband; | 2416 | struct ieee80211_supported_band *sband; |
2413 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2417 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2414 | 2418 | ||
2415 | WARN_ON_ONCE(softirq_count() == 0); | 2419 | WARN_ON_ONCE(softirq_count() == 0); |
2416 | 2420 | ||
2417 | if (WARN_ON(status->band < 0 || | 2421 | if (WARN_ON(status->band < 0 || |
2418 | status->band >= IEEE80211_NUM_BANDS)) | 2422 | status->band >= IEEE80211_NUM_BANDS)) |
2419 | goto drop; | 2423 | goto drop; |
2420 | 2424 | ||
2421 | sband = local->hw.wiphy->bands[status->band]; | 2425 | sband = local->hw.wiphy->bands[status->band]; |
2422 | if (WARN_ON(!sband)) | 2426 | if (WARN_ON(!sband)) |
2423 | goto drop; | 2427 | goto drop; |
2424 | 2428 | ||
2425 | /* | 2429 | /* |
2426 | * If we're suspending, it is possible although not too likely | 2430 | * If we're suspending, it is possible although not too likely |
2427 | * that we'd be receiving frames after having already partially | 2431 | * that we'd be receiving frames after having already partially |
2428 | * quiesced the stack. We can't process such frames then since | 2432 | * quiesced the stack. We can't process such frames then since |
2429 | * that might, for example, cause stations to be added or other | 2433 | * that might, for example, cause stations to be added or other |
2430 | * driver callbacks be invoked. | 2434 | * driver callbacks be invoked. |
2431 | */ | 2435 | */ |
2432 | if (unlikely(local->quiescing || local->suspended)) | 2436 | if (unlikely(local->quiescing || local->suspended)) |
2433 | goto drop; | 2437 | goto drop; |
2434 | 2438 | ||
2435 | /* | 2439 | /* |
2436 | * The same happens when we're not even started, | 2440 | * The same happens when we're not even started, |
2437 | * but that's worth a warning. | 2441 | * but that's worth a warning. |
2438 | */ | 2442 | */ |
2439 | if (WARN_ON(!local->started)) | 2443 | if (WARN_ON(!local->started)) |
2440 | goto drop; | 2444 | goto drop; |
2441 | 2445 | ||
2442 | if (status->flag & RX_FLAG_HT) { | 2446 | if (status->flag & RX_FLAG_HT) { |
2443 | /* | 2447 | /* |
2444 | * rate_idx is MCS index, which can be [0-76] as documented on: | 2448 | * rate_idx is MCS index, which can be [0-76] as documented on: |
2445 | * | 2449 | * |
2446 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n | 2450 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n |
2447 | * | 2451 | * |
2448 | * Anything else would be some sort of driver or hardware error. | 2452 | * Anything else would be some sort of driver or hardware error. |
2449 | * The driver should catch hardware errors. | 2453 | * The driver should catch hardware errors. |
2450 | */ | 2454 | */ |
2451 | if (WARN((status->rate_idx < 0 || | 2455 | if (WARN((status->rate_idx < 0 || |
2452 | status->rate_idx > 76), | 2456 | status->rate_idx > 76), |
2453 | "Rate marked as an HT rate but passed " | 2457 | "Rate marked as an HT rate but passed " |
2454 | "status->rate_idx is not " | 2458 | "status->rate_idx is not " |
2455 | "an MCS index [0-76]: %d (0x%02x)\n", | 2459 | "an MCS index [0-76]: %d (0x%02x)\n", |
2456 | status->rate_idx, | 2460 | status->rate_idx, |
2457 | status->rate_idx)) | 2461 | status->rate_idx)) |
2458 | goto drop; | 2462 | goto drop; |
2459 | /* HT rates are not in the table - use the highest legacy rate | 2463 | /* HT rates are not in the table - use the highest legacy rate |
2460 | * for now since other parts of mac80211 may not yet be fully | 2464 | * for now since other parts of mac80211 may not yet be fully |
2461 | * MCS aware. */ | 2465 | * MCS aware. */ |
2462 | rate = &sband->bitrates[sband->n_bitrates - 1]; | 2466 | rate = &sband->bitrates[sband->n_bitrates - 1]; |
2463 | } else { | 2467 | } else { |
2464 | if (WARN_ON(status->rate_idx < 0 || | 2468 | if (WARN_ON(status->rate_idx < 0 || |
2465 | status->rate_idx >= sband->n_bitrates)) | 2469 | status->rate_idx >= sband->n_bitrates)) |
2466 | goto drop; | 2470 | goto drop; |
2467 | rate = &sband->bitrates[status->rate_idx]; | 2471 | rate = &sband->bitrates[status->rate_idx]; |
2468 | } | 2472 | } |
2469 | 2473 | ||
2470 | /* | 2474 | /* |
2471 | * key references and virtual interfaces are protected using RCU | 2475 | * key references and virtual interfaces are protected using RCU |
2472 | * and this requires that we are in a read-side RCU section during | 2476 | * and this requires that we are in a read-side RCU section during |
2473 | * receive processing | 2477 | * receive processing |
2474 | */ | 2478 | */ |
2475 | rcu_read_lock(); | 2479 | rcu_read_lock(); |
2476 | 2480 | ||
2477 | /* | 2481 | /* |
2478 | * Frames with failed FCS/PLCP checksum are not returned, | 2482 | * Frames with failed FCS/PLCP checksum are not returned, |
2479 | * all other frames are returned without radiotap header | 2483 | * all other frames are returned without radiotap header |
2480 | * if it was previously present. | 2484 | * if it was previously present. |
2481 | * Also, frames with less than 16 bytes are dropped. | 2485 | * Also, frames with less than 16 bytes are dropped. |
2482 | */ | 2486 | */ |
2483 | skb = ieee80211_rx_monitor(local, skb, rate); | 2487 | skb = ieee80211_rx_monitor(local, skb, rate); |
2484 | if (!skb) { | 2488 | if (!skb) { |
2485 | rcu_read_unlock(); | 2489 | rcu_read_unlock(); |
2486 | return; | 2490 | return; |
2487 | } | 2491 | } |
2488 | 2492 | ||
2489 | /* | 2493 | /* |
2490 | * In theory, the block ack reordering should happen after duplicate | 2494 | * In theory, the block ack reordering should happen after duplicate |
2491 | * removal (ieee80211_rx_h_check(), which is an RX handler). As such, | 2495 | * removal (ieee80211_rx_h_check(), which is an RX handler). As such, |
2492 | * the call to ieee80211_rx_reorder_ampdu() should really be moved to | 2496 | * the call to ieee80211_rx_reorder_ampdu() should really be moved to |
2493 | * happen as a new RX handler between ieee80211_rx_h_check and | 2497 | * happen as a new RX handler between ieee80211_rx_h_check and |
2494 | * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for | 2498 | * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for |
2495 | * the time being, the call can be here since RX reorder buf processing | 2499 | * the time being, the call can be here since RX reorder buf processing |
2496 | * will implicitly skip duplicates. We could, in theory at least, | 2500 | * will implicitly skip duplicates. We could, in theory at least, |
2497 | * process frames that ieee80211_rx_h_passive_scan would drop (e.g., | 2501 | * process frames that ieee80211_rx_h_passive_scan would drop (e.g., |
2498 | * frames from other than operational channel), but that should not | 2502 | * frames from other than operational channel), but that should not |
2499 | * happen in normal networks. | 2503 | * happen in normal networks. |
2500 | */ | 2504 | */ |
2501 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2505 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
2502 | __ieee80211_rx_handle_packet(hw, skb, rate); | 2506 | __ieee80211_rx_handle_packet(hw, skb, rate); |
2503 | 2507 | ||
2504 | rcu_read_unlock(); | 2508 | rcu_read_unlock(); |
2505 | 2509 | ||
2506 | return; | 2510 | return; |
2507 | drop: | 2511 | drop: |
2508 | kfree_skb(skb); | 2512 | kfree_skb(skb); |
2509 | } | 2513 | } |
2510 | EXPORT_SYMBOL(ieee80211_rx); | 2514 | EXPORT_SYMBOL(ieee80211_rx); |
2511 | 2515 | ||
2512 | /* This is a version of the rx handler that can be called from hard irq | 2516 | /* This is a version of the rx handler that can be called from hard irq |
2513 | * context. Post the skb on the queue and schedule the tasklet */ | 2517 | * context. Post the skb on the queue and schedule the tasklet */ |
2514 | void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb) | 2518 | void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb) |
2515 | { | 2519 | { |
2516 | struct ieee80211_local *local = hw_to_local(hw); | 2520 | struct ieee80211_local *local = hw_to_local(hw); |
2517 | 2521 | ||
2518 | BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)); | 2522 | BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)); |
net/mac80211/wep.c
1 | /* | 1 | /* |
2 | * Software WEP encryption implementation | 2 | * Software WEP encryption implementation |
3 | * Copyright 2002, Jouni Malinen <jkmaline@cc.hut.fi> | 3 | * Copyright 2002, Jouni Malinen <jkmaline@cc.hut.fi> |
4 | * Copyright 2003, Instant802 Networks, Inc. | 4 | * Copyright 2003, Instant802 Networks, Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/netdevice.h> | 11 | #include <linux/netdevice.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/random.h> | 13 | #include <linux/random.h> |
14 | #include <linux/compiler.h> | 14 | #include <linux/compiler.h> |
15 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
16 | #include <linux/crypto.h> | 16 | #include <linux/crypto.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
21 | 21 | ||
22 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
23 | #include "ieee80211_i.h" | 23 | #include "ieee80211_i.h" |
24 | #include "wep.h" | 24 | #include "wep.h" |
25 | 25 | ||
26 | 26 | ||
27 | int ieee80211_wep_init(struct ieee80211_local *local) | 27 | int ieee80211_wep_init(struct ieee80211_local *local) |
28 | { | 28 | { |
29 | /* start WEP IV from a random value */ | 29 | /* start WEP IV from a random value */ |
30 | get_random_bytes(&local->wep_iv, WEP_IV_LEN); | 30 | get_random_bytes(&local->wep_iv, WEP_IV_LEN); |
31 | 31 | ||
32 | local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, | 32 | local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, |
33 | CRYPTO_ALG_ASYNC); | 33 | CRYPTO_ALG_ASYNC); |
34 | if (IS_ERR(local->wep_tx_tfm)) | 34 | if (IS_ERR(local->wep_tx_tfm)) |
35 | return PTR_ERR(local->wep_tx_tfm); | 35 | return PTR_ERR(local->wep_tx_tfm); |
36 | 36 | ||
37 | local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, | 37 | local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, |
38 | CRYPTO_ALG_ASYNC); | 38 | CRYPTO_ALG_ASYNC); |
39 | if (IS_ERR(local->wep_rx_tfm)) { | 39 | if (IS_ERR(local->wep_rx_tfm)) { |
40 | crypto_free_blkcipher(local->wep_tx_tfm); | 40 | crypto_free_blkcipher(local->wep_tx_tfm); |
41 | return PTR_ERR(local->wep_rx_tfm); | 41 | return PTR_ERR(local->wep_rx_tfm); |
42 | } | 42 | } |
43 | 43 | ||
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | void ieee80211_wep_free(struct ieee80211_local *local) | 47 | void ieee80211_wep_free(struct ieee80211_local *local) |
48 | { | 48 | { |
49 | crypto_free_blkcipher(local->wep_tx_tfm); | 49 | crypto_free_blkcipher(local->wep_tx_tfm); |
50 | crypto_free_blkcipher(local->wep_rx_tfm); | 50 | crypto_free_blkcipher(local->wep_rx_tfm); |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) | 53 | static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) |
54 | { | 54 | { |
55 | /* | 55 | /* |
56 | * Fluhrer, Mantin, and Shamir have reported weaknesses in the | 56 | * Fluhrer, Mantin, and Shamir have reported weaknesses in the |
57 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, | 57 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, |
58 | * 0xff, N) can be used to speedup attacks, so avoid using them. | 58 | * 0xff, N) can be used to speedup attacks, so avoid using them. |
59 | */ | 59 | */ |
60 | if ((iv & 0xff00) == 0xff00) { | 60 | if ((iv & 0xff00) == 0xff00) { |
61 | u8 B = (iv >> 16) & 0xff; | 61 | u8 B = (iv >> 16) & 0xff; |
62 | if (B >= 3 && B < 3 + keylen) | 62 | if (B >= 3 && B < 3 + keylen) |
63 | return true; | 63 | return true; |
64 | } | 64 | } |
65 | return false; | 65 | return false; |
66 | } | 66 | } |
67 | 67 | ||
68 | 68 | ||
69 | static void ieee80211_wep_get_iv(struct ieee80211_local *local, | 69 | static void ieee80211_wep_get_iv(struct ieee80211_local *local, |
70 | int keylen, int keyidx, u8 *iv) | 70 | int keylen, int keyidx, u8 *iv) |
71 | { | 71 | { |
72 | local->wep_iv++; | 72 | local->wep_iv++; |
73 | if (ieee80211_wep_weak_iv(local->wep_iv, keylen)) | 73 | if (ieee80211_wep_weak_iv(local->wep_iv, keylen)) |
74 | local->wep_iv += 0x0100; | 74 | local->wep_iv += 0x0100; |
75 | 75 | ||
76 | if (!iv) | 76 | if (!iv) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | *iv++ = (local->wep_iv >> 16) & 0xff; | 79 | *iv++ = (local->wep_iv >> 16) & 0xff; |
80 | *iv++ = (local->wep_iv >> 8) & 0xff; | 80 | *iv++ = (local->wep_iv >> 8) & 0xff; |
81 | *iv++ = local->wep_iv & 0xff; | 81 | *iv++ = local->wep_iv & 0xff; |
82 | *iv++ = keyidx << 6; | 82 | *iv++ = keyidx << 6; |
83 | } | 83 | } |
84 | 84 | ||
85 | 85 | ||
86 | static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, | 86 | static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, |
87 | struct sk_buff *skb, | 87 | struct sk_buff *skb, |
88 | int keylen, int keyidx) | 88 | int keylen, int keyidx) |
89 | { | 89 | { |
90 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 90 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
91 | unsigned int hdrlen; | 91 | unsigned int hdrlen; |
92 | u8 *newhdr; | 92 | u8 *newhdr; |
93 | 93 | ||
94 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | 94 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
95 | 95 | ||
96 | if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || | 96 | if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || |
97 | skb_headroom(skb) < WEP_IV_LEN)) | 97 | skb_headroom(skb) < WEP_IV_LEN)) |
98 | return NULL; | 98 | return NULL; |
99 | 99 | ||
100 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 100 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
101 | newhdr = skb_push(skb, WEP_IV_LEN); | 101 | newhdr = skb_push(skb, WEP_IV_LEN); |
102 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); | 102 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); |
103 | ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); | 103 | ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); |
104 | return newhdr + hdrlen; | 104 | return newhdr + hdrlen; |
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | static void ieee80211_wep_remove_iv(struct ieee80211_local *local, | 108 | static void ieee80211_wep_remove_iv(struct ieee80211_local *local, |
109 | struct sk_buff *skb, | 109 | struct sk_buff *skb, |
110 | struct ieee80211_key *key) | 110 | struct ieee80211_key *key) |
111 | { | 111 | { |
112 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 112 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
113 | unsigned int hdrlen; | 113 | unsigned int hdrlen; |
114 | 114 | ||
115 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 115 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
116 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 116 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); |
117 | skb_pull(skb, WEP_IV_LEN); | 117 | skb_pull(skb, WEP_IV_LEN); |
118 | } | 118 | } |
119 | 119 | ||
120 | 120 | ||
121 | /* Perform WEP encryption using given key. data buffer must have tailroom | 121 | /* Perform WEP encryption using given key. data buffer must have tailroom |
122 | * for 4-byte ICV. data_len must not include this ICV. Note: this function | 122 | * for 4-byte ICV. data_len must not include this ICV. Note: this function |
123 | * does _not_ add IV. data = RC4(data | CRC32(data)) */ | 123 | * does _not_ add IV. data = RC4(data | CRC32(data)) */ |
124 | void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 124 | void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, |
125 | size_t klen, u8 *data, size_t data_len) | 125 | size_t klen, u8 *data, size_t data_len) |
126 | { | 126 | { |
127 | struct blkcipher_desc desc = { .tfm = tfm }; | 127 | struct blkcipher_desc desc = { .tfm = tfm }; |
128 | struct scatterlist sg; | 128 | struct scatterlist sg; |
129 | __le32 icv; | 129 | __le32 icv; |
130 | 130 | ||
131 | icv = cpu_to_le32(~crc32_le(~0, data, data_len)); | 131 | icv = cpu_to_le32(~crc32_le(~0, data, data_len)); |
132 | put_unaligned(icv, (__le32 *)(data + data_len)); | 132 | put_unaligned(icv, (__le32 *)(data + data_len)); |
133 | 133 | ||
134 | crypto_blkcipher_setkey(tfm, rc4key, klen); | 134 | crypto_blkcipher_setkey(tfm, rc4key, klen); |
135 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); | 135 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); |
136 | crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); | 136 | crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); |
137 | } | 137 | } |
138 | 138 | ||
139 | 139 | ||
140 | /* Perform WEP encryption on given skb. 4 bytes of extra space (IV) in the | 140 | /* Perform WEP encryption on given skb. 4 bytes of extra space (IV) in the |
141 | * beginning of the buffer 4 bytes of extra space (ICV) in the end of the | 141 | * beginning of the buffer 4 bytes of extra space (ICV) in the end of the |
142 | * buffer will be added. Both IV and ICV will be transmitted, so the | 142 | * buffer will be added. Both IV and ICV will be transmitted, so the |
143 | * payload length increases with 8 bytes. | 143 | * payload length increases with 8 bytes. |
144 | * | 144 | * |
145 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) | 145 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) |
146 | */ | 146 | */ |
147 | int ieee80211_wep_encrypt(struct ieee80211_local *local, | 147 | int ieee80211_wep_encrypt(struct ieee80211_local *local, |
148 | struct sk_buff *skb, | 148 | struct sk_buff *skb, |
149 | const u8 *key, int keylen, int keyidx) | 149 | const u8 *key, int keylen, int keyidx) |
150 | { | 150 | { |
151 | u8 *iv; | 151 | u8 *iv; |
152 | size_t len; | 152 | size_t len; |
153 | u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; | 153 | u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; |
154 | 154 | ||
155 | iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); | 155 | iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); |
156 | if (!iv) | 156 | if (!iv) |
157 | return -1; | 157 | return -1; |
158 | 158 | ||
159 | len = skb->len - (iv + WEP_IV_LEN - skb->data); | 159 | len = skb->len - (iv + WEP_IV_LEN - skb->data); |
160 | 160 | ||
161 | /* Prepend 24-bit IV to RC4 key */ | 161 | /* Prepend 24-bit IV to RC4 key */ |
162 | memcpy(rc4key, iv, 3); | 162 | memcpy(rc4key, iv, 3); |
163 | 163 | ||
164 | /* Copy rest of the WEP key (the secret part) */ | 164 | /* Copy rest of the WEP key (the secret part) */ |
165 | memcpy(rc4key + 3, key, keylen); | 165 | memcpy(rc4key + 3, key, keylen); |
166 | 166 | ||
167 | /* Add room for ICV */ | 167 | /* Add room for ICV */ |
168 | skb_put(skb, WEP_ICV_LEN); | 168 | skb_put(skb, WEP_ICV_LEN); |
169 | 169 | ||
170 | ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, | 170 | ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, |
171 | iv + WEP_IV_LEN, len); | 171 | iv + WEP_IV_LEN, len); |
172 | 172 | ||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
175 | 175 | ||
176 | 176 | ||
177 | /* Perform WEP decryption using given key. data buffer includes encrypted | 177 | /* Perform WEP decryption using given key. data buffer includes encrypted |
178 | * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. | 178 | * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. |
179 | * Return 0 on success and -1 on ICV mismatch. */ | 179 | * Return 0 on success and -1 on ICV mismatch. */ |
180 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 180 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, |
181 | size_t klen, u8 *data, size_t data_len) | 181 | size_t klen, u8 *data, size_t data_len) |
182 | { | 182 | { |
183 | struct blkcipher_desc desc = { .tfm = tfm }; | 183 | struct blkcipher_desc desc = { .tfm = tfm }; |
184 | struct scatterlist sg; | 184 | struct scatterlist sg; |
185 | __le32 crc; | 185 | __le32 crc; |
186 | 186 | ||
187 | crypto_blkcipher_setkey(tfm, rc4key, klen); | 187 | crypto_blkcipher_setkey(tfm, rc4key, klen); |
188 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); | 188 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); |
189 | crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); | 189 | crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); |
190 | 190 | ||
191 | crc = cpu_to_le32(~crc32_le(~0, data, data_len)); | 191 | crc = cpu_to_le32(~crc32_le(~0, data, data_len)); |
192 | if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) | 192 | if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) |
193 | /* ICV mismatch */ | 193 | /* ICV mismatch */ |
194 | return -1; | 194 | return -1; |
195 | 195 | ||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | 199 | ||
200 | /* Perform WEP decryption on given skb. Buffer includes whole WEP part of | 200 | /* Perform WEP decryption on given skb. Buffer includes whole WEP part of |
201 | * the frame: IV (4 bytes), encrypted payload (including SNAP header), | 201 | * the frame: IV (4 bytes), encrypted payload (including SNAP header), |
202 | * ICV (4 bytes). skb->len includes both IV and ICV. | 202 | * ICV (4 bytes). skb->len includes both IV and ICV. |
203 | * | 203 | * |
204 | * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on | 204 | * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on |
205 | * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload | 205 | * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload |
206 | * is moved to the beginning of the skb and skb length will be reduced. | 206 | * is moved to the beginning of the skb and skb length will be reduced. |
207 | */ | 207 | */ |
208 | static int ieee80211_wep_decrypt(struct ieee80211_local *local, | 208 | static int ieee80211_wep_decrypt(struct ieee80211_local *local, |
209 | struct sk_buff *skb, | 209 | struct sk_buff *skb, |
210 | struct ieee80211_key *key) | 210 | struct ieee80211_key *key) |
211 | { | 211 | { |
212 | u32 klen; | 212 | u32 klen; |
213 | u8 *rc4key; | 213 | u8 *rc4key; |
214 | u8 keyidx; | 214 | u8 keyidx; |
215 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 215 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
216 | unsigned int hdrlen; | 216 | unsigned int hdrlen; |
217 | size_t len; | 217 | size_t len; |
218 | int ret = 0; | 218 | int ret = 0; |
219 | 219 | ||
220 | if (!ieee80211_has_protected(hdr->frame_control)) | 220 | if (!ieee80211_has_protected(hdr->frame_control)) |
221 | return -1; | 221 | return -1; |
222 | 222 | ||
223 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 223 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
224 | if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN) | 224 | if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN) |
225 | return -1; | 225 | return -1; |
226 | 226 | ||
227 | len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN; | 227 | len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN; |
228 | 228 | ||
229 | keyidx = skb->data[hdrlen + 3] >> 6; | 229 | keyidx = skb->data[hdrlen + 3] >> 6; |
230 | 230 | ||
231 | if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP) | 231 | if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP) |
232 | return -1; | 232 | return -1; |
233 | 233 | ||
234 | klen = 3 + key->conf.keylen; | 234 | klen = 3 + key->conf.keylen; |
235 | 235 | ||
236 | rc4key = kmalloc(klen, GFP_ATOMIC); | 236 | rc4key = kmalloc(klen, GFP_ATOMIC); |
237 | if (!rc4key) | 237 | if (!rc4key) |
238 | return -1; | 238 | return -1; |
239 | 239 | ||
240 | /* Prepend 24-bit IV to RC4 key */ | 240 | /* Prepend 24-bit IV to RC4 key */ |
241 | memcpy(rc4key, skb->data + hdrlen, 3); | 241 | memcpy(rc4key, skb->data + hdrlen, 3); |
242 | 242 | ||
243 | /* Copy rest of the WEP key (the secret part) */ | 243 | /* Copy rest of the WEP key (the secret part) */ |
244 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); | 244 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); |
245 | 245 | ||
246 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, | 246 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
247 | skb->data + hdrlen + WEP_IV_LEN, | 247 | skb->data + hdrlen + WEP_IV_LEN, |
248 | len)) | 248 | len)) |
249 | ret = -1; | 249 | ret = -1; |
250 | 250 | ||
251 | kfree(rc4key); | 251 | kfree(rc4key); |
252 | 252 | ||
253 | /* Trim ICV */ | 253 | /* Trim ICV */ |
254 | skb_trim(skb, skb->len - WEP_ICV_LEN); | 254 | skb_trim(skb, skb->len - WEP_ICV_LEN); |
255 | 255 | ||
256 | /* Remove IV */ | 256 | /* Remove IV */ |
257 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 257 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); |
258 | skb_pull(skb, WEP_IV_LEN); | 258 | skb_pull(skb, WEP_IV_LEN); |
259 | 259 | ||
260 | return ret; | 260 | return ret; |
261 | } | 261 | } |
262 | 262 | ||
263 | 263 | ||
264 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 264 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) |
265 | { | 265 | { |
266 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 266 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
267 | unsigned int hdrlen; | 267 | unsigned int hdrlen; |
268 | u8 *ivpos; | 268 | u8 *ivpos; |
269 | u32 iv; | 269 | u32 iv; |
270 | 270 | ||
271 | if (!ieee80211_has_protected(hdr->frame_control)) | 271 | if (!ieee80211_has_protected(hdr->frame_control)) |
272 | return false; | 272 | return false; |
273 | 273 | ||
274 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 274 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
275 | ivpos = skb->data + hdrlen; | 275 | ivpos = skb->data + hdrlen; |
276 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 276 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
277 | 277 | ||
278 | return ieee80211_wep_weak_iv(iv, key->conf.keylen); | 278 | return ieee80211_wep_weak_iv(iv, key->conf.keylen); |
279 | } | 279 | } |
280 | 280 | ||
281 | ieee80211_rx_result | 281 | ieee80211_rx_result |
282 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | 282 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) |
283 | { | 283 | { |
284 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 284 | struct sk_buff *skb = rx->skb; |
285 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
286 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
285 | 287 | ||
286 | if (!ieee80211_is_data(hdr->frame_control) && | 288 | if (!ieee80211_is_data(hdr->frame_control) && |
287 | !ieee80211_is_auth(hdr->frame_control)) | 289 | !ieee80211_is_auth(hdr->frame_control)) |
288 | return RX_CONTINUE; | 290 | return RX_CONTINUE; |
289 | 291 | ||
290 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 292 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
291 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) | 293 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
292 | return RX_DROP_UNUSABLE; | 294 | return RX_DROP_UNUSABLE; |
293 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { | 295 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { |
294 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 296 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
295 | /* remove ICV */ | 297 | /* remove ICV */ |
296 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); | 298 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); |
297 | } | 299 | } |
298 | 300 | ||
299 | return RX_CONTINUE; | 301 | return RX_CONTINUE; |
300 | } | 302 | } |
301 | 303 | ||
302 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 304 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
303 | { | 305 | { |
304 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 306 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
305 | 307 | ||
306 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 308 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { |
307 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, | 309 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, |
308 | tx->key->conf.keylen, | 310 | tx->key->conf.keylen, |
309 | tx->key->conf.keyidx)) | 311 | tx->key->conf.keyidx)) |
310 | return -1; | 312 | return -1; |
311 | } else { | 313 | } else { |
312 | info->control.hw_key = &tx->key->conf; | 314 | info->control.hw_key = &tx->key->conf; |
313 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { | 315 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { |
314 | if (!ieee80211_wep_add_iv(tx->local, skb, | 316 | if (!ieee80211_wep_add_iv(tx->local, skb, |
315 | tx->key->conf.keylen, | 317 | tx->key->conf.keylen, |
316 | tx->key->conf.keyidx)) | 318 | tx->key->conf.keyidx)) |
317 | return -1; | 319 | return -1; |
318 | } | 320 | } |
319 | } | 321 | } |
320 | return 0; | 322 | return 0; |
321 | } | 323 | } |
322 | 324 | ||
323 | ieee80211_tx_result | 325 | ieee80211_tx_result |
324 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 326 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) |
325 | { | 327 | { |
326 | struct sk_buff *skb; | 328 | struct sk_buff *skb; |
327 | 329 | ||
328 | ieee80211_tx_set_protected(tx); | 330 | ieee80211_tx_set_protected(tx); |
329 | 331 | ||
330 | skb = tx->skb; | 332 | skb = tx->skb; |
331 | do { | 333 | do { |
332 | if (wep_encrypt_skb(tx, skb) < 0) { | 334 | if (wep_encrypt_skb(tx, skb) < 0) { |
333 | I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); | 335 | I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); |
334 | return TX_DROP; | 336 | return TX_DROP; |
335 | } | 337 | } |
336 | } while ((skb = skb->next)); | 338 | } while ((skb = skb->next)); |
337 | 339 | ||
338 | return TX_CONTINUE; | 340 | return TX_CONTINUE; |
339 | } | 341 | } |
340 | 342 |
net/mac80211/wpa.c
1 | /* | 1 | /* |
2 | * Copyright 2002-2004, Instant802 Networks, Inc. | 2 | * Copyright 2002-2004, Instant802 Networks, Inc. |
3 | * Copyright 2008, Jouni Malinen <j@w1.fi> | 3 | * Copyright 2008, Jouni Malinen <j@w1.fi> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/skbuff.h> | 13 | #include <linux/skbuff.h> |
14 | #include <linux/compiler.h> | 14 | #include <linux/compiler.h> |
15 | #include <linux/ieee80211.h> | 15 | #include <linux/ieee80211.h> |
16 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
18 | 18 | ||
19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
20 | #include "michael.h" | 20 | #include "michael.h" |
21 | #include "tkip.h" | 21 | #include "tkip.h" |
22 | #include "aes_ccm.h" | 22 | #include "aes_ccm.h" |
23 | #include "aes_cmac.h" | 23 | #include "aes_cmac.h" |
24 | #include "wpa.h" | 24 | #include "wpa.h" |
25 | 25 | ||
26 | ieee80211_tx_result | 26 | ieee80211_tx_result |
27 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | 27 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) |
28 | { | 28 | { |
29 | u8 *data, *key, *mic, key_offset; | 29 | u8 *data, *key, *mic, key_offset; |
30 | size_t data_len; | 30 | size_t data_len; |
31 | unsigned int hdrlen; | 31 | unsigned int hdrlen; |
32 | struct ieee80211_hdr *hdr; | 32 | struct ieee80211_hdr *hdr; |
33 | struct sk_buff *skb = tx->skb; | 33 | struct sk_buff *skb = tx->skb; |
34 | int authenticator; | 34 | int authenticator; |
35 | int wpa_test = 0; | 35 | int wpa_test = 0; |
36 | int tail; | 36 | int tail; |
37 | 37 | ||
38 | hdr = (struct ieee80211_hdr *)skb->data; | 38 | hdr = (struct ieee80211_hdr *)skb->data; |
39 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || | 39 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || |
40 | !ieee80211_is_data_present(hdr->frame_control)) | 40 | !ieee80211_is_data_present(hdr->frame_control)) |
41 | return TX_CONTINUE; | 41 | return TX_CONTINUE; |
42 | 42 | ||
43 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 43 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
44 | if (skb->len < hdrlen) | 44 | if (skb->len < hdrlen) |
45 | return TX_DROP; | 45 | return TX_DROP; |
46 | 46 | ||
47 | data = skb->data + hdrlen; | 47 | data = skb->data + hdrlen; |
48 | data_len = skb->len - hdrlen; | 48 | data_len = skb->len - hdrlen; |
49 | 49 | ||
50 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 50 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && |
53 | !wpa_test) { | 53 | !wpa_test) { |
54 | /* hwaccel - with no need for preallocated room for MMIC */ | 54 | /* hwaccel - with no need for preallocated room for MMIC */ |
55 | return TX_CONTINUE; | 55 | return TX_CONTINUE; |
56 | } | 56 | } |
57 | 57 | ||
58 | tail = MICHAEL_MIC_LEN; | 58 | tail = MICHAEL_MIC_LEN; |
59 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 59 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
60 | tail += TKIP_ICV_LEN; | 60 | tail += TKIP_ICV_LEN; |
61 | 61 | ||
62 | if (WARN_ON(skb_tailroom(skb) < tail || | 62 | if (WARN_ON(skb_tailroom(skb) < tail || |
63 | skb_headroom(skb) < TKIP_IV_LEN)) | 63 | skb_headroom(skb) < TKIP_IV_LEN)) |
64 | return TX_DROP; | 64 | return TX_DROP; |
65 | 65 | ||
66 | #if 0 | 66 | #if 0 |
67 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ | 67 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ |
68 | #else | 68 | #else |
69 | authenticator = 1; | 69 | authenticator = 1; |
70 | #endif | 70 | #endif |
71 | key_offset = authenticator ? | 71 | key_offset = authenticator ? |
72 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY : | 72 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY : |
73 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | 73 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; |
74 | key = &tx->key->conf.key[key_offset]; | 74 | key = &tx->key->conf.key[key_offset]; |
75 | mic = skb_put(skb, MICHAEL_MIC_LEN); | 75 | mic = skb_put(skb, MICHAEL_MIC_LEN); |
76 | michael_mic(key, hdr, data, data_len, mic); | 76 | michael_mic(key, hdr, data, data_len, mic); |
77 | 77 | ||
78 | return TX_CONTINUE; | 78 | return TX_CONTINUE; |
79 | } | 79 | } |
80 | 80 | ||
81 | 81 | ||
82 | ieee80211_rx_result | 82 | ieee80211_rx_result |
83 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | 83 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) |
84 | { | 84 | { |
85 | u8 *data, *key = NULL, key_offset; | 85 | u8 *data, *key = NULL, key_offset; |
86 | size_t data_len; | 86 | size_t data_len; |
87 | unsigned int hdrlen; | 87 | unsigned int hdrlen; |
88 | struct ieee80211_hdr *hdr; | ||
89 | u8 mic[MICHAEL_MIC_LEN]; | 88 | u8 mic[MICHAEL_MIC_LEN]; |
90 | struct sk_buff *skb = rx->skb; | 89 | struct sk_buff *skb = rx->skb; |
90 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
91 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
91 | int authenticator = 1, wpa_test = 0; | 92 | int authenticator = 1, wpa_test = 0; |
92 | 93 | ||
93 | /* No way to verify the MIC if the hardware stripped it */ | 94 | /* No way to verify the MIC if the hardware stripped it */ |
94 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) | 95 | if (status->flag & RX_FLAG_MMIC_STRIPPED) |
95 | return RX_CONTINUE; | 96 | return RX_CONTINUE; |
96 | 97 | ||
97 | hdr = (struct ieee80211_hdr *)skb->data; | ||
98 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 98 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
99 | !ieee80211_has_protected(hdr->frame_control) || | 99 | !ieee80211_has_protected(hdr->frame_control) || |
100 | !ieee80211_is_data_present(hdr->frame_control)) | 100 | !ieee80211_is_data_present(hdr->frame_control)) |
101 | return RX_CONTINUE; | 101 | return RX_CONTINUE; |
102 | 102 | ||
103 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 103 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
104 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | 104 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
105 | return RX_DROP_UNUSABLE; | 105 | return RX_DROP_UNUSABLE; |
106 | 106 | ||
107 | data = skb->data + hdrlen; | 107 | data = skb->data + hdrlen; |
108 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 108 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
109 | 109 | ||
110 | #if 0 | 110 | #if 0 |
111 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ | 111 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ |
112 | #else | 112 | #else |
113 | authenticator = 1; | 113 | authenticator = 1; |
114 | #endif | 114 | #endif |
115 | key_offset = authenticator ? | 115 | key_offset = authenticator ? |
116 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : | 116 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : |
117 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | 117 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; |
118 | key = &rx->key->conf.key[key_offset]; | 118 | key = &rx->key->conf.key[key_offset]; |
119 | michael_mic(key, hdr, data, data_len, mic); | 119 | michael_mic(key, hdr, data, data_len, mic); |
120 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 120 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
121 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 121 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
122 | return RX_DROP_UNUSABLE; | 122 | return RX_DROP_UNUSABLE; |
123 | 123 | ||
124 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 124 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, |
125 | (void *) skb->data, NULL, | 125 | (void *) skb->data, NULL, |
126 | GFP_ATOMIC); | 126 | GFP_ATOMIC); |
127 | return RX_DROP_UNUSABLE; | 127 | return RX_DROP_UNUSABLE; |
128 | } | 128 | } |
129 | 129 | ||
130 | /* remove Michael MIC from payload */ | 130 | /* remove Michael MIC from payload */ |
131 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 131 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
132 | 132 | ||
133 | /* update IV in key information to be able to detect replays */ | 133 | /* update IV in key information to be able to detect replays */ |
134 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 134 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; |
135 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 135 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; |
136 | 136 | ||
137 | return RX_CONTINUE; | 137 | return RX_CONTINUE; |
138 | } | 138 | } |
139 | 139 | ||
140 | 140 | ||
141 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 141 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
142 | { | 142 | { |
143 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 143 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
144 | struct ieee80211_key *key = tx->key; | 144 | struct ieee80211_key *key = tx->key; |
145 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 145 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
146 | unsigned int hdrlen; | 146 | unsigned int hdrlen; |
147 | int len, tail; | 147 | int len, tail; |
148 | u8 *pos; | 148 | u8 *pos; |
149 | 149 | ||
150 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 150 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
151 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 151 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
152 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 152 | /* hwaccel - with no need for preallocated room for IV/ICV */ |
153 | info->control.hw_key = &tx->key->conf; | 153 | info->control.hw_key = &tx->key->conf; |
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 157 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
158 | len = skb->len - hdrlen; | 158 | len = skb->len - hdrlen; |
159 | 159 | ||
160 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 160 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
161 | tail = 0; | 161 | tail = 0; |
162 | else | 162 | else |
163 | tail = TKIP_ICV_LEN; | 163 | tail = TKIP_ICV_LEN; |
164 | 164 | ||
165 | if (WARN_ON(skb_tailroom(skb) < tail || | 165 | if (WARN_ON(skb_tailroom(skb) < tail || |
166 | skb_headroom(skb) < TKIP_IV_LEN)) | 166 | skb_headroom(skb) < TKIP_IV_LEN)) |
167 | return -1; | 167 | return -1; |
168 | 168 | ||
169 | pos = skb_push(skb, TKIP_IV_LEN); | 169 | pos = skb_push(skb, TKIP_IV_LEN); |
170 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); | 170 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); |
171 | pos += hdrlen; | 171 | pos += hdrlen; |
172 | 172 | ||
173 | /* Increase IV for the frame */ | 173 | /* Increase IV for the frame */ |
174 | key->u.tkip.tx.iv16++; | 174 | key->u.tkip.tx.iv16++; |
175 | if (key->u.tkip.tx.iv16 == 0) | 175 | if (key->u.tkip.tx.iv16 == 0) |
176 | key->u.tkip.tx.iv32++; | 176 | key->u.tkip.tx.iv32++; |
177 | 177 | ||
178 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 178 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
179 | /* hwaccel - with preallocated room for IV */ | 179 | /* hwaccel - with preallocated room for IV */ |
180 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | 180 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
181 | 181 | ||
182 | info->control.hw_key = &tx->key->conf; | 182 | info->control.hw_key = &tx->key->conf; |
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* Add room for ICV */ | 186 | /* Add room for ICV */ |
187 | skb_put(skb, TKIP_ICV_LEN); | 187 | skb_put(skb, TKIP_ICV_LEN); |
188 | 188 | ||
189 | hdr = (struct ieee80211_hdr *) skb->data; | 189 | hdr = (struct ieee80211_hdr *) skb->data; |
190 | ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, | 190 | ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, |
191 | key, pos, len, hdr->addr2); | 191 | key, pos, len, hdr->addr2); |
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | 195 | ||
196 | ieee80211_tx_result | 196 | ieee80211_tx_result |
197 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | 197 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) |
198 | { | 198 | { |
199 | struct sk_buff *skb = tx->skb; | 199 | struct sk_buff *skb = tx->skb; |
200 | 200 | ||
201 | ieee80211_tx_set_protected(tx); | 201 | ieee80211_tx_set_protected(tx); |
202 | 202 | ||
203 | do { | 203 | do { |
204 | if (tkip_encrypt_skb(tx, skb) < 0) | 204 | if (tkip_encrypt_skb(tx, skb) < 0) |
205 | return TX_DROP; | 205 | return TX_DROP; |
206 | } while ((skb = skb->next)); | 206 | } while ((skb = skb->next)); |
207 | 207 | ||
208 | return TX_CONTINUE; | 208 | return TX_CONTINUE; |
209 | } | 209 | } |
210 | 210 | ||
211 | 211 | ||
212 | ieee80211_rx_result | 212 | ieee80211_rx_result |
213 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | 213 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) |
214 | { | 214 | { |
215 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 215 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
216 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 216 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
217 | struct ieee80211_key *key = rx->key; | 217 | struct ieee80211_key *key = rx->key; |
218 | struct sk_buff *skb = rx->skb; | 218 | struct sk_buff *skb = rx->skb; |
219 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
219 | 220 | ||
220 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 221 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
221 | 222 | ||
222 | if (!ieee80211_is_data(hdr->frame_control)) | 223 | if (!ieee80211_is_data(hdr->frame_control)) |
223 | return RX_CONTINUE; | 224 | return RX_CONTINUE; |
224 | 225 | ||
225 | if (!rx->sta || skb->len - hdrlen < 12) | 226 | if (!rx->sta || skb->len - hdrlen < 12) |
226 | return RX_DROP_UNUSABLE; | 227 | return RX_DROP_UNUSABLE; |
227 | 228 | ||
228 | if (rx->status->flag & RX_FLAG_DECRYPTED) { | 229 | if (status->flag & RX_FLAG_DECRYPTED) { |
229 | if (rx->status->flag & RX_FLAG_IV_STRIPPED) { | 230 | if (status->flag & RX_FLAG_IV_STRIPPED) { |
230 | /* | 231 | /* |
231 | * Hardware took care of all processing, including | 232 | * Hardware took care of all processing, including |
232 | * replay protection, and stripped the ICV/IV so | 233 | * replay protection, and stripped the ICV/IV so |
233 | * we cannot do any checks here. | 234 | * we cannot do any checks here. |
234 | */ | 235 | */ |
235 | return RX_CONTINUE; | 236 | return RX_CONTINUE; |
236 | } | 237 | } |
237 | 238 | ||
238 | /* let TKIP code verify IV, but skip decryption */ | 239 | /* let TKIP code verify IV, but skip decryption */ |
239 | hwaccel = 1; | 240 | hwaccel = 1; |
240 | } | 241 | } |
241 | 242 | ||
242 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 243 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
243 | key, skb->data + hdrlen, | 244 | key, skb->data + hdrlen, |
244 | skb->len - hdrlen, rx->sta->sta.addr, | 245 | skb->len - hdrlen, rx->sta->sta.addr, |
245 | hdr->addr1, hwaccel, rx->queue, | 246 | hdr->addr1, hwaccel, rx->queue, |
246 | &rx->tkip_iv32, | 247 | &rx->tkip_iv32, |
247 | &rx->tkip_iv16); | 248 | &rx->tkip_iv16); |
248 | if (res != TKIP_DECRYPT_OK || wpa_test) | 249 | if (res != TKIP_DECRYPT_OK || wpa_test) |
249 | return RX_DROP_UNUSABLE; | 250 | return RX_DROP_UNUSABLE; |
250 | 251 | ||
251 | /* Trim ICV */ | 252 | /* Trim ICV */ |
252 | skb_trim(skb, skb->len - TKIP_ICV_LEN); | 253 | skb_trim(skb, skb->len - TKIP_ICV_LEN); |
253 | 254 | ||
254 | /* Remove IV */ | 255 | /* Remove IV */ |
255 | memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); | 256 | memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); |
256 | skb_pull(skb, TKIP_IV_LEN); | 257 | skb_pull(skb, TKIP_IV_LEN); |
257 | 258 | ||
258 | return RX_CONTINUE; | 259 | return RX_CONTINUE; |
259 | } | 260 | } |
260 | 261 | ||
261 | 262 | ||
262 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | 263 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, |
263 | int encrypted) | 264 | int encrypted) |
264 | { | 265 | { |
265 | __le16 mask_fc; | 266 | __le16 mask_fc; |
266 | int a4_included, mgmt; | 267 | int a4_included, mgmt; |
267 | u8 qos_tid; | 268 | u8 qos_tid; |
268 | u8 *b_0, *aad; | 269 | u8 *b_0, *aad; |
269 | u16 data_len, len_a; | 270 | u16 data_len, len_a; |
270 | unsigned int hdrlen; | 271 | unsigned int hdrlen; |
271 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 272 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
272 | 273 | ||
273 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 274 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
274 | aad = scratch + 4 * AES_BLOCK_LEN; | 275 | aad = scratch + 4 * AES_BLOCK_LEN; |
275 | 276 | ||
276 | /* | 277 | /* |
277 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) | 278 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) |
278 | * Retry, PwrMgt, MoreData; set Protected | 279 | * Retry, PwrMgt, MoreData; set Protected |
279 | */ | 280 | */ |
280 | mgmt = ieee80211_is_mgmt(hdr->frame_control); | 281 | mgmt = ieee80211_is_mgmt(hdr->frame_control); |
281 | mask_fc = hdr->frame_control; | 282 | mask_fc = hdr->frame_control; |
282 | mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | | 283 | mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | |
283 | IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); | 284 | IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); |
284 | if (!mgmt) | 285 | if (!mgmt) |
285 | mask_fc &= ~cpu_to_le16(0x0070); | 286 | mask_fc &= ~cpu_to_le16(0x0070); |
286 | mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | 287 | mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
287 | 288 | ||
288 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 289 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
289 | len_a = hdrlen - 2; | 290 | len_a = hdrlen - 2; |
290 | a4_included = ieee80211_has_a4(hdr->frame_control); | 291 | a4_included = ieee80211_has_a4(hdr->frame_control); |
291 | 292 | ||
292 | if (ieee80211_is_data_qos(hdr->frame_control)) | 293 | if (ieee80211_is_data_qos(hdr->frame_control)) |
293 | qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 294 | qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
294 | else | 295 | else |
295 | qos_tid = 0; | 296 | qos_tid = 0; |
296 | 297 | ||
297 | data_len = skb->len - hdrlen - CCMP_HDR_LEN; | 298 | data_len = skb->len - hdrlen - CCMP_HDR_LEN; |
298 | if (encrypted) | 299 | if (encrypted) |
299 | data_len -= CCMP_MIC_LEN; | 300 | data_len -= CCMP_MIC_LEN; |
300 | 301 | ||
301 | /* First block, b_0 */ | 302 | /* First block, b_0 */ |
302 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ | 303 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ |
303 | /* Nonce: Nonce Flags | A2 | PN | 304 | /* Nonce: Nonce Flags | A2 | PN |
304 | * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) | 305 | * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) |
305 | */ | 306 | */ |
306 | b_0[1] = qos_tid | (mgmt << 4); | 307 | b_0[1] = qos_tid | (mgmt << 4); |
307 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); | 308 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
308 | memcpy(&b_0[8], pn, CCMP_PN_LEN); | 309 | memcpy(&b_0[8], pn, CCMP_PN_LEN); |
309 | /* l(m) */ | 310 | /* l(m) */ |
310 | put_unaligned_be16(data_len, &b_0[14]); | 311 | put_unaligned_be16(data_len, &b_0[14]); |
311 | 312 | ||
312 | /* AAD (extra authenticate-only data) / masked 802.11 header | 313 | /* AAD (extra authenticate-only data) / masked 802.11 header |
313 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ | 314 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |
314 | put_unaligned_be16(len_a, &aad[0]); | 315 | put_unaligned_be16(len_a, &aad[0]); |
315 | put_unaligned(mask_fc, (__le16 *)&aad[2]); | 316 | put_unaligned(mask_fc, (__le16 *)&aad[2]); |
316 | memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); | 317 | memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); |
317 | 318 | ||
318 | /* Mask Seq#, leave Frag# */ | 319 | /* Mask Seq#, leave Frag# */ |
319 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; | 320 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; |
320 | aad[23] = 0; | 321 | aad[23] = 0; |
321 | 322 | ||
322 | if (a4_included) { | 323 | if (a4_included) { |
323 | memcpy(&aad[24], hdr->addr4, ETH_ALEN); | 324 | memcpy(&aad[24], hdr->addr4, ETH_ALEN); |
324 | aad[30] = qos_tid; | 325 | aad[30] = qos_tid; |
325 | aad[31] = 0; | 326 | aad[31] = 0; |
326 | } else { | 327 | } else { |
327 | memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); | 328 | memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); |
328 | aad[24] = qos_tid; | 329 | aad[24] = qos_tid; |
329 | } | 330 | } |
330 | } | 331 | } |
331 | 332 | ||
332 | 333 | ||
333 | static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id) | 334 | static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id) |
334 | { | 335 | { |
335 | hdr[0] = pn[5]; | 336 | hdr[0] = pn[5]; |
336 | hdr[1] = pn[4]; | 337 | hdr[1] = pn[4]; |
337 | hdr[2] = 0; | 338 | hdr[2] = 0; |
338 | hdr[3] = 0x20 | (key_id << 6); | 339 | hdr[3] = 0x20 | (key_id << 6); |
339 | hdr[4] = pn[3]; | 340 | hdr[4] = pn[3]; |
340 | hdr[5] = pn[2]; | 341 | hdr[5] = pn[2]; |
341 | hdr[6] = pn[1]; | 342 | hdr[6] = pn[1]; |
342 | hdr[7] = pn[0]; | 343 | hdr[7] = pn[0]; |
343 | } | 344 | } |
344 | 345 | ||
345 | 346 | ||
346 | static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr) | 347 | static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr) |
347 | { | 348 | { |
348 | pn[0] = hdr[7]; | 349 | pn[0] = hdr[7]; |
349 | pn[1] = hdr[6]; | 350 | pn[1] = hdr[6]; |
350 | pn[2] = hdr[5]; | 351 | pn[2] = hdr[5]; |
351 | pn[3] = hdr[4]; | 352 | pn[3] = hdr[4]; |
352 | pn[4] = hdr[1]; | 353 | pn[4] = hdr[1]; |
353 | pn[5] = hdr[0]; | 354 | pn[5] = hdr[0]; |
354 | } | 355 | } |
355 | 356 | ||
356 | 357 | ||
357 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 358 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
358 | { | 359 | { |
359 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 360 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
360 | struct ieee80211_key *key = tx->key; | 361 | struct ieee80211_key *key = tx->key; |
361 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 362 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
362 | int hdrlen, len, tail; | 363 | int hdrlen, len, tail; |
363 | u8 *pos, *pn; | 364 | u8 *pos, *pn; |
364 | int i; | 365 | int i; |
365 | bool skip_hw; | 366 | bool skip_hw; |
366 | 367 | ||
367 | skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) && | 368 | skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) && |
368 | ieee80211_is_mgmt(hdr->frame_control); | 369 | ieee80211_is_mgmt(hdr->frame_control); |
369 | 370 | ||
370 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 371 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
371 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | 372 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && |
372 | !skip_hw) { | 373 | !skip_hw) { |
373 | /* hwaccel - with no need for preallocated room for CCMP | 374 | /* hwaccel - with no need for preallocated room for CCMP |
374 | * header or MIC fields */ | 375 | * header or MIC fields */ |
375 | info->control.hw_key = &tx->key->conf; | 376 | info->control.hw_key = &tx->key->conf; |
376 | return 0; | 377 | return 0; |
377 | } | 378 | } |
378 | 379 | ||
379 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 380 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
380 | len = skb->len - hdrlen; | 381 | len = skb->len - hdrlen; |
381 | 382 | ||
382 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 383 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
383 | tail = 0; | 384 | tail = 0; |
384 | else | 385 | else |
385 | tail = CCMP_MIC_LEN; | 386 | tail = CCMP_MIC_LEN; |
386 | 387 | ||
387 | if (WARN_ON(skb_tailroom(skb) < tail || | 388 | if (WARN_ON(skb_tailroom(skb) < tail || |
388 | skb_headroom(skb) < CCMP_HDR_LEN)) | 389 | skb_headroom(skb) < CCMP_HDR_LEN)) |
389 | return -1; | 390 | return -1; |
390 | 391 | ||
391 | pos = skb_push(skb, CCMP_HDR_LEN); | 392 | pos = skb_push(skb, CCMP_HDR_LEN); |
392 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 393 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |
393 | hdr = (struct ieee80211_hdr *) pos; | 394 | hdr = (struct ieee80211_hdr *) pos; |
394 | pos += hdrlen; | 395 | pos += hdrlen; |
395 | 396 | ||
396 | /* PN = PN + 1 */ | 397 | /* PN = PN + 1 */ |
397 | pn = key->u.ccmp.tx_pn; | 398 | pn = key->u.ccmp.tx_pn; |
398 | 399 | ||
399 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 400 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { |
400 | pn[i]++; | 401 | pn[i]++; |
401 | if (pn[i]) | 402 | if (pn[i]) |
402 | break; | 403 | break; |
403 | } | 404 | } |
404 | 405 | ||
405 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); | 406 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); |
406 | 407 | ||
407 | if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) { | 408 | if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) { |
408 | /* hwaccel - with preallocated room for CCMP header */ | 409 | /* hwaccel - with preallocated room for CCMP header */ |
409 | info->control.hw_key = &tx->key->conf; | 410 | info->control.hw_key = &tx->key->conf; |
410 | return 0; | 411 | return 0; |
411 | } | 412 | } |
412 | 413 | ||
413 | pos += CCMP_HDR_LEN; | 414 | pos += CCMP_HDR_LEN; |
414 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); | 415 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); |
415 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len, | 416 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len, |
416 | pos, skb_put(skb, CCMP_MIC_LEN)); | 417 | pos, skb_put(skb, CCMP_MIC_LEN)); |
417 | 418 | ||
418 | return 0; | 419 | return 0; |
419 | } | 420 | } |
420 | 421 | ||
421 | 422 | ||
422 | ieee80211_tx_result | 423 | ieee80211_tx_result |
423 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 424 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) |
424 | { | 425 | { |
425 | struct sk_buff *skb = tx->skb; | 426 | struct sk_buff *skb = tx->skb; |
426 | 427 | ||
427 | ieee80211_tx_set_protected(tx); | 428 | ieee80211_tx_set_protected(tx); |
428 | 429 | ||
429 | do { | 430 | do { |
430 | if (ccmp_encrypt_skb(tx, skb) < 0) | 431 | if (ccmp_encrypt_skb(tx, skb) < 0) |
431 | return TX_DROP; | 432 | return TX_DROP; |
432 | } while ((skb = skb->next)); | 433 | } while ((skb = skb->next)); |
433 | 434 | ||
434 | return TX_CONTINUE; | 435 | return TX_CONTINUE; |
435 | } | 436 | } |
436 | 437 | ||
437 | 438 | ||
438 | ieee80211_rx_result | 439 | ieee80211_rx_result |
439 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | 440 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) |
440 | { | 441 | { |
441 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 442 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
442 | int hdrlen; | 443 | int hdrlen; |
443 | struct ieee80211_key *key = rx->key; | 444 | struct ieee80211_key *key = rx->key; |
444 | struct sk_buff *skb = rx->skb; | 445 | struct sk_buff *skb = rx->skb; |
446 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
445 | u8 pn[CCMP_PN_LEN]; | 447 | u8 pn[CCMP_PN_LEN]; |
446 | int data_len; | 448 | int data_len; |
447 | 449 | ||
448 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 450 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
449 | 451 | ||
450 | if (!ieee80211_is_data(hdr->frame_control) && | 452 | if (!ieee80211_is_data(hdr->frame_control) && |
451 | !ieee80211_is_robust_mgmt_frame(hdr)) | 453 | !ieee80211_is_robust_mgmt_frame(hdr)) |
452 | return RX_CONTINUE; | 454 | return RX_CONTINUE; |
453 | 455 | ||
454 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; | 456 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; |
455 | if (!rx->sta || data_len < 0) | 457 | if (!rx->sta || data_len < 0) |
456 | return RX_DROP_UNUSABLE; | 458 | return RX_DROP_UNUSABLE; |
457 | 459 | ||
458 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 460 | if ((status->flag & RX_FLAG_DECRYPTED) && |
459 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 461 | (status->flag & RX_FLAG_IV_STRIPPED)) |
460 | return RX_CONTINUE; | 462 | return RX_CONTINUE; |
461 | 463 | ||
462 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 464 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
463 | 465 | ||
464 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { | 466 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { |
465 | key->u.ccmp.replays++; | 467 | key->u.ccmp.replays++; |
466 | return RX_DROP_UNUSABLE; | 468 | return RX_DROP_UNUSABLE; |
467 | } | 469 | } |
468 | 470 | ||
469 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 471 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
470 | /* hardware didn't decrypt/verify MIC */ | 472 | /* hardware didn't decrypt/verify MIC */ |
471 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); | 473 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); |
472 | 474 | ||
473 | if (ieee80211_aes_ccm_decrypt( | 475 | if (ieee80211_aes_ccm_decrypt( |
474 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, | 476 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, |
475 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 477 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
476 | skb->data + skb->len - CCMP_MIC_LEN, | 478 | skb->data + skb->len - CCMP_MIC_LEN, |
477 | skb->data + hdrlen + CCMP_HDR_LEN)) | 479 | skb->data + hdrlen + CCMP_HDR_LEN)) |
478 | return RX_DROP_UNUSABLE; | 480 | return RX_DROP_UNUSABLE; |
479 | } | 481 | } |
480 | 482 | ||
481 | memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN); | 483 | memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN); |
482 | 484 | ||
483 | /* Remove CCMP header and MIC */ | 485 | /* Remove CCMP header and MIC */ |
484 | skb_trim(skb, skb->len - CCMP_MIC_LEN); | 486 | skb_trim(skb, skb->len - CCMP_MIC_LEN); |
485 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); | 487 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); |
486 | skb_pull(skb, CCMP_HDR_LEN); | 488 | skb_pull(skb, CCMP_HDR_LEN); |
487 | 489 | ||
488 | return RX_CONTINUE; | 490 | return RX_CONTINUE; |
489 | } | 491 | } |
490 | 492 | ||
491 | 493 | ||
492 | static void bip_aad(struct sk_buff *skb, u8 *aad) | 494 | static void bip_aad(struct sk_buff *skb, u8 *aad) |
493 | { | 495 | { |
494 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ | 496 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ |
495 | 497 | ||
496 | /* FC type/subtype */ | 498 | /* FC type/subtype */ |
497 | aad[0] = skb->data[0]; | 499 | aad[0] = skb->data[0]; |
498 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ | 500 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ |
499 | aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); | 501 | aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); |
500 | /* A1 || A2 || A3 */ | 502 | /* A1 || A2 || A3 */ |
501 | memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); | 503 | memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); |
502 | } | 504 | } |
503 | 505 | ||
504 | 506 | ||
505 | static inline void bip_ipn_swap(u8 *d, const u8 *s) | 507 | static inline void bip_ipn_swap(u8 *d, const u8 *s) |
506 | { | 508 | { |
507 | *d++ = s[5]; | 509 | *d++ = s[5]; |
508 | *d++ = s[4]; | 510 | *d++ = s[4]; |
509 | *d++ = s[3]; | 511 | *d++ = s[3]; |
510 | *d++ = s[2]; | 512 | *d++ = s[2]; |
511 | *d++ = s[1]; | 513 | *d++ = s[1]; |
512 | *d = s[0]; | 514 | *d = s[0]; |
513 | } | 515 | } |
514 | 516 | ||
515 | 517 | ||
516 | ieee80211_tx_result | 518 | ieee80211_tx_result |
517 | ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) | 519 | ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) |
518 | { | 520 | { |
519 | struct sk_buff *skb = tx->skb; | 521 | struct sk_buff *skb = tx->skb; |
520 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 522 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
521 | struct ieee80211_key *key = tx->key; | 523 | struct ieee80211_key *key = tx->key; |
522 | struct ieee80211_mmie *mmie; | 524 | struct ieee80211_mmie *mmie; |
523 | u8 *pn, aad[20]; | 525 | u8 *pn, aad[20]; |
524 | int i; | 526 | int i; |
525 | 527 | ||
526 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 528 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
527 | /* hwaccel */ | 529 | /* hwaccel */ |
528 | info->control.hw_key = &tx->key->conf; | 530 | info->control.hw_key = &tx->key->conf; |
529 | return 0; | 531 | return 0; |
530 | } | 532 | } |
531 | 533 | ||
532 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) | 534 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) |
533 | return TX_DROP; | 535 | return TX_DROP; |
534 | 536 | ||
535 | mmie = (struct ieee80211_mmie *) skb_put(skb, sizeof(*mmie)); | 537 | mmie = (struct ieee80211_mmie *) skb_put(skb, sizeof(*mmie)); |
536 | mmie->element_id = WLAN_EID_MMIE; | 538 | mmie->element_id = WLAN_EID_MMIE; |
537 | mmie->length = sizeof(*mmie) - 2; | 539 | mmie->length = sizeof(*mmie) - 2; |
538 | mmie->key_id = cpu_to_le16(key->conf.keyidx); | 540 | mmie->key_id = cpu_to_le16(key->conf.keyidx); |
539 | 541 | ||
540 | /* PN = PN + 1 */ | 542 | /* PN = PN + 1 */ |
541 | pn = key->u.aes_cmac.tx_pn; | 543 | pn = key->u.aes_cmac.tx_pn; |
542 | 544 | ||
543 | for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { | 545 | for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { |
544 | pn[i]++; | 546 | pn[i]++; |
545 | if (pn[i]) | 547 | if (pn[i]) |
546 | break; | 548 | break; |
547 | } | 549 | } |
548 | bip_ipn_swap(mmie->sequence_number, pn); | 550 | bip_ipn_swap(mmie->sequence_number, pn); |
549 | 551 | ||
550 | bip_aad(skb, aad); | 552 | bip_aad(skb, aad); |
551 | 553 | ||
552 | /* | 554 | /* |
553 | * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) | 555 | * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) |
554 | */ | 556 | */ |
555 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, | 557 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, |
556 | aad, skb->data + 24, skb->len - 24, mmie->mic); | 558 | aad, skb->data + 24, skb->len - 24, mmie->mic); |
557 | 559 | ||
558 | return TX_CONTINUE; | 560 | return TX_CONTINUE; |
559 | } | 561 | } |
560 | 562 | ||
561 | 563 | ||
562 | ieee80211_rx_result | 564 | ieee80211_rx_result |
563 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | 565 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) |
564 | { | 566 | { |
565 | struct sk_buff *skb = rx->skb; | 567 | struct sk_buff *skb = rx->skb; |
568 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
566 | struct ieee80211_key *key = rx->key; | 569 | struct ieee80211_key *key = rx->key; |
567 | struct ieee80211_mmie *mmie; | 570 | struct ieee80211_mmie *mmie; |
568 | u8 aad[20], mic[8], ipn[6]; | 571 | u8 aad[20], mic[8], ipn[6]; |
569 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 572 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
570 | 573 | ||
571 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 574 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
572 | return RX_CONTINUE; | 575 | return RX_CONTINUE; |
573 | 576 | ||
574 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 577 | if ((status->flag & RX_FLAG_DECRYPTED) && |
575 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 578 | (status->flag & RX_FLAG_IV_STRIPPED)) |
576 | return RX_CONTINUE; | 579 | return RX_CONTINUE; |
577 | 580 | ||
578 | if (skb->len < 24 + sizeof(*mmie)) | 581 | if (skb->len < 24 + sizeof(*mmie)) |
579 | return RX_DROP_UNUSABLE; | 582 | return RX_DROP_UNUSABLE; |
580 | 583 | ||
581 | mmie = (struct ieee80211_mmie *) | 584 | mmie = (struct ieee80211_mmie *) |
582 | (skb->data + skb->len - sizeof(*mmie)); | 585 | (skb->data + skb->len - sizeof(*mmie)); |
583 | if (mmie->element_id != WLAN_EID_MMIE || | 586 | if (mmie->element_id != WLAN_EID_MMIE || |
584 | mmie->length != sizeof(*mmie) - 2) | 587 | mmie->length != sizeof(*mmie) - 2) |
585 | return RX_DROP_UNUSABLE; /* Invalid MMIE */ | 588 | return RX_DROP_UNUSABLE; /* Invalid MMIE */ |
586 | 589 | ||
587 | bip_ipn_swap(ipn, mmie->sequence_number); | 590 | bip_ipn_swap(ipn, mmie->sequence_number); |
588 | 591 | ||
589 | if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) { | 592 | if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) { |
590 | key->u.aes_cmac.replays++; | 593 | key->u.aes_cmac.replays++; |
591 | return RX_DROP_UNUSABLE; | 594 | return RX_DROP_UNUSABLE; |
592 | } | 595 | } |
593 | 596 | ||
594 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 597 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
595 | /* hardware didn't decrypt/verify MIC */ | 598 | /* hardware didn't decrypt/verify MIC */ |
596 | bip_aad(skb, aad); | 599 | bip_aad(skb, aad); |
597 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, | 600 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, |
598 | key->u.aes_cmac.rx_crypto_buf, aad, | 601 | key->u.aes_cmac.rx_crypto_buf, aad, |
599 | skb->data + 24, skb->len - 24, mic); | 602 | skb->data + 24, skb->len - 24, mic); |
600 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { | 603 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { |
601 | key->u.aes_cmac.icverrors++; | 604 | key->u.aes_cmac.icverrors++; |
602 | return RX_DROP_UNUSABLE; | 605 | return RX_DROP_UNUSABLE; |
603 | } | 606 | } |
604 | } | 607 | } |
605 | 608 | ||
606 | memcpy(key->u.aes_cmac.rx_pn, ipn, 6); | 609 | memcpy(key->u.aes_cmac.rx_pn, ipn, 6); |
607 | 610 | ||
608 | /* Remove MMIE */ | 611 | /* Remove MMIE */ |
609 | skb_trim(skb, skb->len - sizeof(*mmie)); | 612 | skb_trim(skb, skb->len - sizeof(*mmie)); |
610 | 613 | ||
611 | return RX_CONTINUE; | 614 | return RX_CONTINUE; |