aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-08-29 14:52:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-29 14:52:20 -0400
commitba6e5eb107b4b26444cb67ce6fb8eb0973a97964 (patch)
tree9377baf652e0cd8360372020b0386e238d07a30d /net/mac80211
parentf3116f62cb56ef5efd172371fab688bb27529f69 (diff)
parenta508a6ea234571e0e7d1e9f2455fc1eca54d1fef (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/Kconfig13
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/cfg.c19
-rw-r--r--net/mac80211/debugfs_netdev.c8
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mesh.c259
-rw-r--r--net/mac80211/mesh.h36
-rw-r--r--net/mac80211/mesh_hwmp.c130
-rw-r--r--net/mac80211/mesh_pathtbl.c305
-rw-r--r--net/mac80211/mesh_plink.c241
-rw-r--r--net/mac80211/mlme.c59
-rw-r--r--net/mac80211/rx.c48
-rw-r--r--net/mac80211/sta_info.c330
-rw-r--r--net/mac80211/sta_info.h30
-rw-r--r--net/mac80211/status.c18
-rw-r--r--net/mac80211/tx.c14
16 files changed, 1148 insertions, 365 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index f5fdfcbf552a..d1886b59bec4 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -199,6 +199,19 @@ config MAC80211_VERBOSE_MPL_DEBUG
199 199
200 Do not select this option. 200 Do not select this option.
201 201
202config MAC80211_VERBOSE_MPATH_DEBUG
203 bool "Verbose mesh path debugging"
204 depends on MAC80211_DEBUG_MENU
205 depends on MAC80211_MESH
206 ---help---
207 Selecting this option causes mac80211 to print out very
208 verbose mesh path selection debugging messages (when mac80211
209 is taking part in a mesh network).
210 It should not be selected on production systems as those
211 messages are remotely triggerable.
212
213 Do not select this option.
214
202config MAC80211_VERBOSE_MHWMP_DEBUG 215config MAC80211_VERBOSE_MHWMP_DEBUG
203 bool "Verbose mesh HWMP routing debugging" 216 bool "Verbose mesh HWMP routing debugging"
204 depends on MAC80211_DEBUG_MENU 217 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index b7075f33dc06..018108d1a2fd 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -128,7 +128,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
128 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN); 128 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
131 bar_control |= (u16)(tid << 12); 131 bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
132 bar->control = cpu_to_le16(bar_control); 132 bar->control = cpu_to_le16(bar_control);
133 bar->start_seq_num = cpu_to_le16(ssn); 133 bar->start_seq_num = cpu_to_le16(ssn);
134 134
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a589addf6ce1..4baa03b1c251 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -697,6 +697,9 @@ static void sta_apply_parameters(struct ieee80211_local *local,
697 } 697 }
698 spin_unlock_irqrestore(&sta->flaglock, flags); 698 spin_unlock_irqrestore(&sta->flaglock, flags);
699 699
700 sta->sta.uapsd_queues = params->uapsd_queues;
701 sta->sta.max_sp = params->max_sp;
702
700 /* 703 /*
701 * cfg80211 validates this (1-2007) and allows setting the AID 704 * cfg80211 validates this (1-2007) and allows setting the AID
702 * only when creating a new station entry 705 * only when creating a new station entry
@@ -1137,6 +1140,22 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1137 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode; 1140 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1138 ieee80211_mesh_root_setup(ifmsh); 1141 ieee80211_mesh_root_setup(ifmsh);
1139 } 1142 }
1143 if (_chg_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask)) {
1144 /* our current gate announcement implementation rides on root
1145 * announcements, so require this ifmsh to also be a root node
1146 * */
1147 if (nconf->dot11MeshGateAnnouncementProtocol &&
1148 !conf->dot11MeshHWMPRootMode) {
1149 conf->dot11MeshHWMPRootMode = 1;
1150 ieee80211_mesh_root_setup(ifmsh);
1151 }
1152 conf->dot11MeshGateAnnouncementProtocol =
1153 nconf->dot11MeshGateAnnouncementProtocol;
1154 }
1155 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
1156 conf->dot11MeshHWMPRannInterval =
1157 nconf->dot11MeshHWMPRannInterval;
1158 }
1140 return 0; 1159 return 0;
1141} 1160}
1142 1161
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 9ea7c0d0103f..6e8eab7919e2 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -372,6 +372,10 @@ IEEE80211_IF_FILE(min_discovery_timeout,
372 u.mesh.mshcfg.min_discovery_timeout, DEC); 372 u.mesh.mshcfg.min_discovery_timeout, DEC);
373IEEE80211_IF_FILE(dot11MeshHWMPRootMode, 373IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
374 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); 374 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
375IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
376 u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
377IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
378 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
375#endif 379#endif
376 380
377 381
@@ -485,7 +489,9 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
485 MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); 489 MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
486 MESHPARAMS_ADD(path_refresh_time); 490 MESHPARAMS_ADD(path_refresh_time);
487 MESHPARAMS_ADD(min_discovery_timeout); 491 MESHPARAMS_ADD(min_discovery_timeout);
488 492 MESHPARAMS_ADD(dot11MeshHWMPRootMode);
493 MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
494 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
489#undef MESHPARAMS_ADD 495#undef MESHPARAMS_ADD
490} 496}
491#endif 497#endif
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ea7419050846..c204cee1189c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -514,6 +514,7 @@ struct ieee80211_if_mesh {
514 struct mesh_config mshcfg; 514 struct mesh_config mshcfg;
515 u32 mesh_seqnum; 515 u32 mesh_seqnum;
516 bool accepting_plinks; 516 bool accepting_plinks;
517 int num_gates;
517 const u8 *ie; 518 const u8 *ie;
518 u8 ie_len; 519 u8 ie_len;
519 enum { 520 enum {
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 29e9980c8e60..28ab510e621a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -13,10 +13,6 @@
13#include "ieee80211_i.h" 13#include "ieee80211_i.h"
14#include "mesh.h" 14#include "mesh.h"
15 15
16#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
17#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
18#define IEEE80211_MESH_RANN_INTERVAL (1 * HZ)
19
20#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01 16#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
21#define MESHCONF_CAPAB_FORWARDING 0x08 17#define MESHCONF_CAPAB_FORWARDING 0x08
22 18
@@ -27,6 +23,17 @@
27int mesh_allocated; 23int mesh_allocated;
28static struct kmem_cache *rm_cache; 24static struct kmem_cache *rm_cache;
29 25
26#ifdef CONFIG_MAC80211_MESH
27bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
28{
29 return (mgmt->u.action.u.mesh_action.action_code ==
30 WLAN_MESH_ACTION_HWMP_PATH_SELECTION);
31}
32#else
33bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
34{ return false; }
35#endif
36
30void ieee80211s_init(void) 37void ieee80211s_init(void)
31{ 38{
32 mesh_pathtbl_init(); 39 mesh_pathtbl_init();
@@ -204,36 +211,185 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
204 return 0; 211 return 0;
205} 212}
206 213
207void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 214int
215mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
216{
217 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
218 u8 *pos, neighbors;
219 u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
220
221 if (skb_tailroom(skb) < 2 + meshconf_len)
222 return -ENOMEM;
223
224 pos = skb_put(skb, 2 + meshconf_len);
225 *pos++ = WLAN_EID_MESH_CONFIG;
226 *pos++ = meshconf_len;
227
228 /* Active path selection protocol ID */
229 *pos++ = ifmsh->mesh_pp_id;
230 /* Active path selection metric ID */
231 *pos++ = ifmsh->mesh_pm_id;
232 /* Congestion control mode identifier */
233 *pos++ = ifmsh->mesh_cc_id;
234 /* Synchronization protocol identifier */
235 *pos++ = ifmsh->mesh_sp_id;
236 /* Authentication Protocol identifier */
237 *pos++ = ifmsh->mesh_auth_id;
238 /* Mesh Formation Info - number of neighbors */
239 neighbors = atomic_read(&ifmsh->mshstats.estab_plinks);
240 /* Number of neighbor mesh STAs or 15 whichever is smaller */
241 neighbors = (neighbors > 15) ? 15 : neighbors;
242 *pos++ = neighbors << 1;
243 /* Mesh capability */
244 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
245 *pos = MESHCONF_CAPAB_FORWARDING;
246 *pos++ |= ifmsh->accepting_plinks ?
247 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
248 *pos++ = 0x00;
249
250 return 0;
251}
252
253int
254mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
255{
256 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
257 u8 *pos;
258
259 if (skb_tailroom(skb) < 2 + ifmsh->mesh_id_len)
260 return -ENOMEM;
261
262 pos = skb_put(skb, 2 + ifmsh->mesh_id_len);
263 *pos++ = WLAN_EID_MESH_ID;
264 *pos++ = ifmsh->mesh_id_len;
265 if (ifmsh->mesh_id_len)
266 memcpy(pos, ifmsh->mesh_id, ifmsh->mesh_id_len);
267
268 return 0;
269}
270
271int
272mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
273{
274 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
275 u8 offset, len;
276 const u8 *data;
277
278 if (!ifmsh->ie || !ifmsh->ie_len)
279 return 0;
280
281 /* fast-forward to vendor IEs */
282 offset = ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0);
283
284 if (offset) {
285 len = ifmsh->ie_len - offset;
286 data = ifmsh->ie + offset;
287 if (skb_tailroom(skb) < len)
288 return -ENOMEM;
289 memcpy(skb_put(skb, len), data, len);
290 }
291
292 return 0;
293}
294
295int
296mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
297{
298 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
299 u8 len = 0;
300 const u8 *data;
301
302 if (!ifmsh->ie || !ifmsh->ie_len)
303 return 0;
304
305 /* find RSN IE */
306 data = ifmsh->ie;
307 while (data < ifmsh->ie + ifmsh->ie_len) {
308 if (*data == WLAN_EID_RSN) {
309 len = data[1] + 2;
310 break;
311 }
312 data++;
313 }
314
315 if (len) {
316 if (skb_tailroom(skb) < len)
317 return -ENOMEM;
318 memcpy(skb_put(skb, len), data, len);
319 }
320
321 return 0;
322}
323
324int
325mesh_add_srates_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
208{ 326{
209 struct ieee80211_local *local = sdata->local; 327 struct ieee80211_local *local = sdata->local;
210 struct ieee80211_supported_band *sband; 328 struct ieee80211_supported_band *sband;
211 u8 *pos; 329 int rate;
212 int len, i, rate; 330 u8 i, rates, *pos;
213 u8 neighbors;
214 331
215 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 332 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
216 len = sband->n_bitrates; 333 rates = sband->n_bitrates;
217 if (len > 8) 334 if (rates > 8)
218 len = 8; 335 rates = 8;
219 pos = skb_put(skb, len + 2); 336
337 if (skb_tailroom(skb) < rates + 2)
338 return -ENOMEM;
339
340 pos = skb_put(skb, rates + 2);
220 *pos++ = WLAN_EID_SUPP_RATES; 341 *pos++ = WLAN_EID_SUPP_RATES;
221 *pos++ = len; 342 *pos++ = rates;
222 for (i = 0; i < len; i++) { 343 for (i = 0; i < rates; i++) {
223 rate = sband->bitrates[i].bitrate; 344 rate = sband->bitrates[i].bitrate;
224 *pos++ = (u8) (rate / 5); 345 *pos++ = (u8) (rate / 5);
225 } 346 }
226 347
227 if (sband->n_bitrates > len) { 348 return 0;
228 pos = skb_put(skb, sband->n_bitrates - len + 2); 349}
350
351int
352mesh_add_ext_srates_ie(struct sk_buff *skb,
353 struct ieee80211_sub_if_data *sdata)
354{
355 struct ieee80211_local *local = sdata->local;
356 struct ieee80211_supported_band *sband;
357 int rate;
358 u8 i, exrates, *pos;
359
360 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
361 exrates = sband->n_bitrates;
362 if (exrates > 8)
363 exrates -= 8;
364 else
365 exrates = 0;
366
367 if (skb_tailroom(skb) < exrates + 2)
368 return -ENOMEM;
369
370 if (exrates) {
371 pos = skb_put(skb, exrates + 2);
229 *pos++ = WLAN_EID_EXT_SUPP_RATES; 372 *pos++ = WLAN_EID_EXT_SUPP_RATES;
230 *pos++ = sband->n_bitrates - len; 373 *pos++ = exrates;
231 for (i = len; i < sband->n_bitrates; i++) { 374 for (i = 8; i < sband->n_bitrates; i++) {
232 rate = sband->bitrates[i].bitrate; 375 rate = sband->bitrates[i].bitrate;
233 *pos++ = (u8) (rate / 5); 376 *pos++ = (u8) (rate / 5);
234 } 377 }
235 } 378 }
379 return 0;
380}
236 381
382int mesh_add_ds_params_ie(struct sk_buff *skb,
383 struct ieee80211_sub_if_data *sdata)
384{
385 struct ieee80211_local *local = sdata->local;
386 struct ieee80211_supported_band *sband;
387 u8 *pos;
388
389 if (skb_tailroom(skb) < 3)
390 return -ENOMEM;
391
392 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
237 if (sband->band == IEEE80211_BAND_2GHZ) { 393 if (sband->band == IEEE80211_BAND_2GHZ) {
238 pos = skb_put(skb, 2 + 1); 394 pos = skb_put(skb, 2 + 1);
239 *pos++ = WLAN_EID_DS_PARAMS; 395 *pos++ = WLAN_EID_DS_PARAMS;
@@ -241,53 +397,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
241 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq); 397 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq);
242 } 398 }
243 399
244 pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len); 400 return 0;
245 *pos++ = WLAN_EID_MESH_ID;
246 *pos++ = sdata->u.mesh.mesh_id_len;
247 if (sdata->u.mesh.mesh_id_len)
248 memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len);
249
250 pos = skb_put(skb, 2 + sizeof(struct ieee80211_meshconf_ie));
251 *pos++ = WLAN_EID_MESH_CONFIG;
252 *pos++ = sizeof(struct ieee80211_meshconf_ie);
253
254 /* Active path selection protocol ID */
255 *pos++ = sdata->u.mesh.mesh_pp_id;
256
257 /* Active path selection metric ID */
258 *pos++ = sdata->u.mesh.mesh_pm_id;
259
260 /* Congestion control mode identifier */
261 *pos++ = sdata->u.mesh.mesh_cc_id;
262
263 /* Synchronization protocol identifier */
264 *pos++ = sdata->u.mesh.mesh_sp_id;
265
266 /* Authentication Protocol identifier */
267 *pos++ = sdata->u.mesh.mesh_auth_id;
268
269 /* Mesh Formation Info - number of neighbors */
270 neighbors = atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
271 /* Number of neighbor mesh STAs or 15 whichever is smaller */
272 neighbors = (neighbors > 15) ? 15 : neighbors;
273 *pos++ = neighbors << 1;
274
275 /* Mesh capability */
276 sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
277 *pos = MESHCONF_CAPAB_FORWARDING;
278 *pos++ |= sdata->u.mesh.accepting_plinks ?
279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
280 *pos++ = 0x00;
281
282 if (sdata->u.mesh.ie) {
283 int len = sdata->u.mesh.ie_len;
284 const u8 *data = sdata->u.mesh.ie;
285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len);
287 }
288} 401}
289 402
290
291static void ieee80211_mesh_path_timer(unsigned long data) 403static void ieee80211_mesh_path_timer(unsigned long data)
292{ 404{
293 struct ieee80211_sub_if_data *sdata = 405 struct ieee80211_sub_if_data *sdata =
@@ -425,7 +537,8 @@ static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
425 537
426 mesh_path_tx_root_frame(sdata); 538 mesh_path_tx_root_frame(sdata);
427 mod_timer(&ifmsh->mesh_path_root_timer, 539 mod_timer(&ifmsh->mesh_path_root_timer,
428 round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL)); 540 round_jiffies(TU_TO_EXP_TIME(
541 ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
429} 542}
430 543
431#ifdef CONFIG_PM 544#ifdef CONFIG_PM
@@ -433,7 +546,7 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
433{ 546{
434 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 547 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
435 548
436 /* use atomic bitops in case both timers fire at the same time */ 549 /* use atomic bitops in case all timers fire at the same time */
437 550
438 if (del_timer_sync(&ifmsh->housekeeping_timer)) 551 if (del_timer_sync(&ifmsh->housekeeping_timer))
439 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); 552 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
@@ -557,11 +670,18 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
557 struct ieee80211_rx_status *rx_status) 670 struct ieee80211_rx_status *rx_status)
558{ 671{
559 switch (mgmt->u.action.category) { 672 switch (mgmt->u.action.category) {
560 case WLAN_CATEGORY_MESH_ACTION: 673 case WLAN_CATEGORY_SELF_PROTECTED:
561 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 674 switch (mgmt->u.action.u.self_prot.action_code) {
675 case WLAN_SP_MESH_PEERING_OPEN:
676 case WLAN_SP_MESH_PEERING_CLOSE:
677 case WLAN_SP_MESH_PEERING_CONFIRM:
678 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
679 break;
680 }
562 break; 681 break;
563 case WLAN_CATEGORY_MESH_PATH_SEL: 682 case WLAN_CATEGORY_MESH_ACTION:
564 mesh_rx_path_sel_frame(sdata, mgmt, len); 683 if (mesh_action_is_path_sel(mgmt))
684 mesh_rx_path_sel_frame(sdata, mgmt, len);
565 break; 685 break;
566 } 686 }
567} 687}
@@ -633,6 +753,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
633 ifmsh->accepting_plinks = true; 753 ifmsh->accepting_plinks = true;
634 ifmsh->preq_id = 0; 754 ifmsh->preq_id = 0;
635 ifmsh->sn = 0; 755 ifmsh->sn = 0;
756 ifmsh->num_gates = 0;
636 atomic_set(&ifmsh->mpaths, 0); 757 atomic_set(&ifmsh->mpaths, 0);
637 mesh_rmc_init(sdata); 758 mesh_rmc_init(sdata);
638 ifmsh->last_preq = jiffies; 759 ifmsh->last_preq = jiffies;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 249e733362e7..20272072171f 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -81,6 +81,7 @@ enum mesh_deferred_task_flags {
81 * @discovery_retries: number of discovery retries 81 * @discovery_retries: number of discovery retries
82 * @flags: mesh path flags, as specified on &enum mesh_path_flags 82 * @flags: mesh path flags, as specified on &enum mesh_path_flags
83 * @state_lock: mesh path state lock 83 * @state_lock: mesh path state lock
84 * @is_gate: the destination station of this path is a mesh gate
84 * 85 *
85 * 86 *
86 * The combination of dst and sdata is unique in the mesh path table. Since the 87 * The combination of dst and sdata is unique in the mesh path table. Since the
@@ -104,6 +105,7 @@ struct mesh_path {
104 u8 discovery_retries; 105 u8 discovery_retries;
105 enum mesh_path_flags flags; 106 enum mesh_path_flags flags;
106 spinlock_t state_lock; 107 spinlock_t state_lock;
108 bool is_gate;
107}; 109};
108 110
109/** 111/**
@@ -120,6 +122,9 @@ struct mesh_path {
120 * buckets 122 * buckets
121 * @mean_chain_len: maximum average length for the hash buckets' list, if it is 123 * @mean_chain_len: maximum average length for the hash buckets' list, if it is
122 * reached, the table will grow 124 * reached, the table will grow
125 * @known_gates: list of known mesh gates and their mpaths by the station. The
126 * gate's mpath may or may not be resolved and active.
127 *
123 * rcu_head: RCU head to free the table 128 * rcu_head: RCU head to free the table
124 */ 129 */
125struct mesh_table { 130struct mesh_table {
@@ -133,6 +138,8 @@ struct mesh_table {
133 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); 138 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
134 int size_order; 139 int size_order;
135 int mean_chain_len; 140 int mean_chain_len;
141 struct hlist_head *known_gates;
142 spinlock_t gates_lock;
136 143
137 struct rcu_head rcu_head; 144 struct rcu_head rcu_head;
138}; 145};
@@ -166,6 +173,8 @@ struct mesh_rmc {
166 u32 idx_mask; 173 u32 idx_mask;
167}; 174};
168 175
176#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
177#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
169 178
170#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ 179#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
171 180
@@ -177,14 +186,6 @@ struct mesh_rmc {
177/* Maximum number of paths per interface */ 186/* Maximum number of paths per interface */
178#define MESH_MAX_MPATHS 1024 187#define MESH_MAX_MPATHS 1024
179 188
180/* Pending ANA approval */
181#define MESH_PATH_SEL_ACTION 0
182
183/* PERR reason codes */
184#define PEER_RCODE_UNSPECIFIED 11
185#define PERR_RCODE_NO_ROUTE 12
186#define PERR_RCODE_DEST_UNREACH 13
187
188/* Public interfaces */ 189/* Public interfaces */
189/* Various */ 190/* Various */
190int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 191int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
@@ -199,6 +200,20 @@ bool mesh_matches_local(struct ieee802_11_elems *ie,
199void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 200void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
200void mesh_mgmt_ies_add(struct sk_buff *skb, 201void mesh_mgmt_ies_add(struct sk_buff *skb,
201 struct ieee80211_sub_if_data *sdata); 202 struct ieee80211_sub_if_data *sdata);
203int mesh_add_meshconf_ie(struct sk_buff *skb,
204 struct ieee80211_sub_if_data *sdata);
205int mesh_add_meshid_ie(struct sk_buff *skb,
206 struct ieee80211_sub_if_data *sdata);
207int mesh_add_rsn_ie(struct sk_buff *skb,
208 struct ieee80211_sub_if_data *sdata);
209int mesh_add_vendor_ies(struct sk_buff *skb,
210 struct ieee80211_sub_if_data *sdata);
211int mesh_add_srates_ie(struct sk_buff *skb,
212 struct ieee80211_sub_if_data *sdata);
213int mesh_add_ext_srates_ie(struct sk_buff *skb,
214 struct ieee80211_sub_if_data *sdata);
215int mesh_add_ds_params_ie(struct sk_buff *skb,
216 struct ieee80211_sub_if_data *sdata);
202void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 217void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
203int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 218int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
204void ieee80211s_init(void); 219void ieee80211s_init(void);
@@ -227,6 +242,10 @@ void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
227void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 242void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
228 struct ieee80211_mgmt *mgmt, size_t len); 243 struct ieee80211_mgmt *mgmt, size_t len);
229int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); 244int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
245
246int mesh_path_add_gate(struct mesh_path *mpath);
247int mesh_path_send_to_gates(struct mesh_path *mpath);
248int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
230/* Mesh plinks */ 249/* Mesh plinks */
231void mesh_neighbour_update(u8 *hw_addr, u32 rates, 250void mesh_neighbour_update(u8 *hw_addr, u32 rates,
232 struct ieee80211_sub_if_data *sdata, 251 struct ieee80211_sub_if_data *sdata,
@@ -262,6 +281,7 @@ void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
262void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 281void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
263void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 282void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
264 283
284bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
265extern int mesh_paths_generation; 285extern int mesh_paths_generation;
266 286
267#ifdef CONFIG_MAC80211_MESH 287#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3d8e55ae6ab6..fd4f76a3e139 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -11,7 +11,8 @@
11#include "mesh.h" 11#include "mesh.h"
12 12
13#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG 13#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
14#define mhwmp_dbg(fmt, args...) printk(KERN_DEBUG "Mesh HWMP: " fmt, ##args) 14#define mhwmp_dbg(fmt, args...) \
15 printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args)
15#else 16#else
16#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) 17#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0)
17#endif 18#endif
@@ -68,12 +69,12 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
68#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) 69#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
69#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) 70#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
70#define PREP_IE_TTL(x) PREQ_IE_TTL(x) 71#define PREP_IE_TTL(x) PREQ_IE_TTL(x)
71#define PREP_IE_ORIG_ADDR(x) (x + 3) 72#define PREP_IE_ORIG_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
72#define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0) 73#define PREP_IE_ORIG_SN(x) u32_field_get(x, 27, AE_F_SET(x))
73#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)) 74#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x))
74#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)) 75#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x))
75#define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) 76#define PREP_IE_TARGET_ADDR(x) (x + 3)
76#define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)) 77#define PREP_IE_TARGET_SN(x) u32_field_get(x, 9, 0)
77 78
78#define PERR_IE_TTL(x) (*(x)) 79#define PERR_IE_TTL(x) (*(x))
79#define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) 80#define PERR_IE_TARGET_FLAGS(x) (*(x + 2))
@@ -132,24 +133,25 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
132 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 133 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
133 /* BSSID == SA */ 134 /* BSSID == SA */
134 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 135 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
135 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; 136 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
136 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 137 mgmt->u.action.u.mesh_action.action_code =
138 WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
137 139
138 switch (action) { 140 switch (action) {
139 case MPATH_PREQ: 141 case MPATH_PREQ:
140 mhwmp_dbg("sending PREQ to %pM\n", target); 142 mhwmp_dbg("sending PREQ to %pM", target);
141 ie_len = 37; 143 ie_len = 37;
142 pos = skb_put(skb, 2 + ie_len); 144 pos = skb_put(skb, 2 + ie_len);
143 *pos++ = WLAN_EID_PREQ; 145 *pos++ = WLAN_EID_PREQ;
144 break; 146 break;
145 case MPATH_PREP: 147 case MPATH_PREP:
146 mhwmp_dbg("sending PREP to %pM\n", target); 148 mhwmp_dbg("sending PREP to %pM", target);
147 ie_len = 31; 149 ie_len = 31;
148 pos = skb_put(skb, 2 + ie_len); 150 pos = skb_put(skb, 2 + ie_len);
149 *pos++ = WLAN_EID_PREP; 151 *pos++ = WLAN_EID_PREP;
150 break; 152 break;
151 case MPATH_RANN: 153 case MPATH_RANN:
152 mhwmp_dbg("sending RANN from %pM\n", orig_addr); 154 mhwmp_dbg("sending RANN from %pM", orig_addr);
153 ie_len = sizeof(struct ieee80211_rann_ie); 155 ie_len = sizeof(struct ieee80211_rann_ie);
154 pos = skb_put(skb, 2 + ie_len); 156 pos = skb_put(skb, 2 + ie_len);
155 *pos++ = WLAN_EID_RANN; 157 *pos++ = WLAN_EID_RANN;
@@ -163,29 +165,37 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
163 *pos++ = flags; 165 *pos++ = flags;
164 *pos++ = hop_count; 166 *pos++ = hop_count;
165 *pos++ = ttl; 167 *pos++ = ttl;
166 if (action == MPATH_PREQ) { 168 if (action == MPATH_PREP) {
167 memcpy(pos, &preq_id, 4); 169 memcpy(pos, target, ETH_ALEN);
170 pos += ETH_ALEN;
171 memcpy(pos, &target_sn, 4);
168 pos += 4; 172 pos += 4;
169 } 173 } else {
170 memcpy(pos, orig_addr, ETH_ALEN); 174 if (action == MPATH_PREQ) {
171 pos += ETH_ALEN; 175 memcpy(pos, &preq_id, 4);
172 memcpy(pos, &orig_sn, 4); 176 pos += 4;
173 pos += 4; 177 }
174 if (action != MPATH_RANN) { 178 memcpy(pos, orig_addr, ETH_ALEN);
175 memcpy(pos, &lifetime, 4); 179 pos += ETH_ALEN;
180 memcpy(pos, &orig_sn, 4);
176 pos += 4; 181 pos += 4;
177 } 182 }
183 memcpy(pos, &lifetime, 4); /* interval for RANN */
184 pos += 4;
178 memcpy(pos, &metric, 4); 185 memcpy(pos, &metric, 4);
179 pos += 4; 186 pos += 4;
180 if (action == MPATH_PREQ) { 187 if (action == MPATH_PREQ) {
181 /* destination count */ 188 *pos++ = 1; /* destination count */
182 *pos++ = 1;
183 *pos++ = target_flags; 189 *pos++ = target_flags;
184 }
185 if (action != MPATH_RANN) {
186 memcpy(pos, target, ETH_ALEN); 190 memcpy(pos, target, ETH_ALEN);
187 pos += ETH_ALEN; 191 pos += ETH_ALEN;
188 memcpy(pos, &target_sn, 4); 192 memcpy(pos, &target_sn, 4);
193 pos += 4;
194 } else if (action == MPATH_PREP) {
195 memcpy(pos, orig_addr, ETH_ALEN);
196 pos += ETH_ALEN;
197 memcpy(pos, &orig_sn, 4);
198 pos += 4;
189 } 199 }
190 200
191 ieee80211_tx_skb(sdata, skb); 201 ieee80211_tx_skb(sdata, skb);
@@ -224,9 +234,11 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
224 234
225 memcpy(mgmt->da, ra, ETH_ALEN); 235 memcpy(mgmt->da, ra, ETH_ALEN);
226 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 236 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
227 /* BSSID is left zeroed, wildcard value */ 237 /* BSSID == SA */
228 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; 238 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
229 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 239 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
240 mgmt->u.action.u.mesh_action.action_code =
241 WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
230 ie_len = 15; 242 ie_len = 15;
231 pos = skb_put(skb, 2 + ie_len); 243 pos = skb_put(skb, 2 + ie_len);
232 *pos++ = WLAN_EID_PERR; 244 *pos++ = WLAN_EID_PERR;
@@ -483,10 +495,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
483 orig_sn = PREQ_IE_ORIG_SN(preq_elem); 495 orig_sn = PREQ_IE_ORIG_SN(preq_elem);
484 target_flags = PREQ_IE_TARGET_F(preq_elem); 496 target_flags = PREQ_IE_TARGET_F(preq_elem);
485 497
486 mhwmp_dbg("received PREQ from %pM\n", orig_addr); 498 mhwmp_dbg("received PREQ from %pM", orig_addr);
487 499
488 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { 500 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
489 mhwmp_dbg("PREQ is for us\n"); 501 mhwmp_dbg("PREQ is for us");
490 forward = false; 502 forward = false;
491 reply = true; 503 reply = true;
492 metric = 0; 504 metric = 0;
@@ -522,7 +534,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
522 lifetime = PREQ_IE_LIFETIME(preq_elem); 534 lifetime = PREQ_IE_LIFETIME(preq_elem);
523 ttl = ifmsh->mshcfg.element_ttl; 535 ttl = ifmsh->mshcfg.element_ttl;
524 if (ttl != 0) { 536 if (ttl != 0) {
525 mhwmp_dbg("replying to the PREQ\n"); 537 mhwmp_dbg("replying to the PREQ");
526 mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr, 538 mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr,
527 cpu_to_le32(target_sn), 0, orig_addr, 539 cpu_to_le32(target_sn), 0, orig_addr,
528 cpu_to_le32(orig_sn), mgmt->sa, 0, ttl, 540 cpu_to_le32(orig_sn), mgmt->sa, 0, ttl,
@@ -542,7 +554,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
542 ifmsh->mshstats.dropped_frames_ttl++; 554 ifmsh->mshstats.dropped_frames_ttl++;
543 return; 555 return;
544 } 556 }
545 mhwmp_dbg("forwarding the PREQ from %pM\n", orig_addr); 557 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
546 --ttl; 558 --ttl;
547 flags = PREQ_IE_FLAGS(preq_elem); 559 flags = PREQ_IE_FLAGS(preq_elem);
548 preq_id = PREQ_IE_PREQ_ID(preq_elem); 560 preq_id = PREQ_IE_PREQ_ID(preq_elem);
@@ -577,7 +589,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
577 u8 next_hop[ETH_ALEN]; 589 u8 next_hop[ETH_ALEN];
578 u32 target_sn, orig_sn, lifetime; 590 u32 target_sn, orig_sn, lifetime;
579 591
580 mhwmp_dbg("received PREP from %pM\n", PREP_IE_ORIG_ADDR(prep_elem)); 592 mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
581 593
582 /* Note that we divert from the draft nomenclature and denominate 594 /* Note that we divert from the draft nomenclature and denominate
583 * destination to what the draft refers to as origininator. So in this 595 * destination to what the draft refers to as origininator. So in this
@@ -683,6 +695,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
683 u8 ttl, flags, hopcount; 695 u8 ttl, flags, hopcount;
684 u8 *orig_addr; 696 u8 *orig_addr;
685 u32 orig_sn, metric; 697 u32 orig_sn, metric;
698 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
699 bool root_is_gate;
686 700
687 ttl = rann->rann_ttl; 701 ttl = rann->rann_ttl;
688 if (ttl <= 1) { 702 if (ttl <= 1) {
@@ -691,12 +705,19 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
691 } 705 }
692 ttl--; 706 ttl--;
693 flags = rann->rann_flags; 707 flags = rann->rann_flags;
708 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
694 orig_addr = rann->rann_addr; 709 orig_addr = rann->rann_addr;
695 orig_sn = rann->rann_seq; 710 orig_sn = rann->rann_seq;
696 hopcount = rann->rann_hopcount; 711 hopcount = rann->rann_hopcount;
697 hopcount++; 712 hopcount++;
698 metric = rann->rann_metric; 713 metric = rann->rann_metric;
699 mhwmp_dbg("received RANN from %pM\n", orig_addr); 714
715 /* Ignore our own RANNs */
716 if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
717 return;
718
719 mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
720 root_is_gate);
700 721
701 rcu_read_lock(); 722 rcu_read_lock();
702 mpath = mesh_path_lookup(orig_addr, sdata); 723 mpath = mesh_path_lookup(orig_addr, sdata);
@@ -708,18 +729,28 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
708 sdata->u.mesh.mshstats.dropped_frames_no_route++; 729 sdata->u.mesh.mshstats.dropped_frames_no_route++;
709 return; 730 return;
710 } 731 }
711 mesh_queue_preq(mpath,
712 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
713 } 732 }
733
734 if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
735 time_after(jiffies, mpath->exp_time - 1*HZ)) &&
736 !(mpath->flags & MESH_PATH_FIXED)) {
737 mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
738 orig_addr);
739 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
740 }
741
714 if (mpath->sn < orig_sn) { 742 if (mpath->sn < orig_sn) {
715 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 743 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
716 cpu_to_le32(orig_sn), 744 cpu_to_le32(orig_sn),
717 0, NULL, 0, broadcast_addr, 745 0, NULL, 0, broadcast_addr,
718 hopcount, ttl, 0, 746 hopcount, ttl, cpu_to_le32(interval),
719 cpu_to_le32(metric + mpath->metric), 747 cpu_to_le32(metric + mpath->metric),
720 0, sdata); 748 0, sdata);
721 mpath->sn = orig_sn; 749 mpath->sn = orig_sn;
722 } 750 }
751 if (root_is_gate)
752 mesh_path_add_gate(mpath);
753
723 rcu_read_unlock(); 754 rcu_read_unlock();
724} 755}
725 756
@@ -787,7 +818,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
787 818
788 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); 819 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
789 if (!preq_node) { 820 if (!preq_node) {
790 mhwmp_dbg("could not allocate PREQ node\n"); 821 mhwmp_dbg("could not allocate PREQ node");
791 return; 822 return;
792 } 823 }
793 824
@@ -796,7 +827,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
796 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); 827 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
797 kfree(preq_node); 828 kfree(preq_node);
798 if (printk_ratelimit()) 829 if (printk_ratelimit())
799 mhwmp_dbg("PREQ node queue full\n"); 830 mhwmp_dbg("PREQ node queue full");
800 return; 831 return;
801 } 832 }
802 833
@@ -981,35 +1012,46 @@ void mesh_path_timer(unsigned long data)
981{ 1012{
982 struct mesh_path *mpath = (void *) data; 1013 struct mesh_path *mpath = (void *) data;
983 struct ieee80211_sub_if_data *sdata = mpath->sdata; 1014 struct ieee80211_sub_if_data *sdata = mpath->sdata;
1015 int ret;
984 1016
985 if (sdata->local->quiescing) 1017 if (sdata->local->quiescing)
986 return; 1018 return;
987 1019
988 spin_lock_bh(&mpath->state_lock); 1020 spin_lock_bh(&mpath->state_lock);
989 if (mpath->flags & MESH_PATH_RESOLVED || 1021 if (mpath->flags & MESH_PATH_RESOLVED ||
990 (!(mpath->flags & MESH_PATH_RESOLVING))) 1022 (!(mpath->flags & MESH_PATH_RESOLVING))) {
991 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); 1023 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
992 else if (mpath->discovery_retries < max_preq_retries(sdata)) { 1024 spin_unlock_bh(&mpath->state_lock);
1025 } else if (mpath->discovery_retries < max_preq_retries(sdata)) {
993 ++mpath->discovery_retries; 1026 ++mpath->discovery_retries;
994 mpath->discovery_timeout *= 2; 1027 mpath->discovery_timeout *= 2;
1028 spin_unlock_bh(&mpath->state_lock);
995 mesh_queue_preq(mpath, 0); 1029 mesh_queue_preq(mpath, 0);
996 } else { 1030 } else {
997 mpath->flags = 0; 1031 mpath->flags = 0;
998 mpath->exp_time = jiffies; 1032 mpath->exp_time = jiffies;
999 mesh_path_flush_pending(mpath); 1033 spin_unlock_bh(&mpath->state_lock);
1034 if (!mpath->is_gate && mesh_gate_num(sdata) > 0) {
1035 ret = mesh_path_send_to_gates(mpath);
1036 if (ret)
1037 mhwmp_dbg("no gate was reachable");
1038 } else
1039 mesh_path_flush_pending(mpath);
1000 } 1040 }
1001
1002 spin_unlock_bh(&mpath->state_lock);
1003} 1041}
1004 1042
1005void 1043void
1006mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) 1044mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1007{ 1045{
1008 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1046 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1047 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
1048 u8 flags;
1009 1049
1010 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, 1050 flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
1051 ? RANN_FLAG_IS_GATE : 0;
1052 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1011 cpu_to_le32(++ifmsh->sn), 1053 cpu_to_le32(++ifmsh->sn),
1012 0, NULL, 0, broadcast_addr, 1054 0, NULL, 0, broadcast_addr,
1013 0, sdata->u.mesh.mshcfg.element_ttl, 1055 0, sdata->u.mesh.mshcfg.element_ttl,
1014 0, 0, 0, sdata); 1056 cpu_to_le32(interval), 0, 0, sdata);
1015} 1057}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index dc7ae8d31aaf..7fde32159fdc 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -17,6 +17,12 @@
17#include "ieee80211_i.h" 17#include "ieee80211_i.h"
18#include "mesh.h" 18#include "mesh.h"
19 19
20#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG
21#define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
22#else
23#define mpath_dbg(fmt, args...) do { (void)(0); } while (0)
24#endif
25
20/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ 26/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */
21#define INIT_PATHS_SIZE_ORDER 2 27#define INIT_PATHS_SIZE_ORDER 2
22 28
@@ -60,6 +66,8 @@ static inline struct mesh_table *resize_dereference_mpp_paths(void)
60 lockdep_is_held(&pathtbl_resize_lock)); 66 lockdep_is_held(&pathtbl_resize_lock));
61} 67}
62 68
69static int mesh_gate_add(struct mesh_table *tbl, struct mesh_path *mpath);
70
63/* 71/*
64 * CAREFUL -- "tbl" must not be an expression, 72 * CAREFUL -- "tbl" must not be an expression,
65 * in particular not an rcu_dereference(), since 73 * in particular not an rcu_dereference(), since
@@ -103,6 +111,7 @@ static struct mesh_table *mesh_table_alloc(int size_order)
103 sizeof(newtbl->hash_rnd)); 111 sizeof(newtbl->hash_rnd));
104 for (i = 0; i <= newtbl->hash_mask; i++) 112 for (i = 0; i <= newtbl->hash_mask; i++)
105 spin_lock_init(&newtbl->hashwlock[i]); 113 spin_lock_init(&newtbl->hashwlock[i]);
114 spin_lock_init(&newtbl->gates_lock);
106 115
107 return newtbl; 116 return newtbl;
108} 117}
@@ -118,6 +127,7 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
118{ 127{
119 struct hlist_head *mesh_hash; 128 struct hlist_head *mesh_hash;
120 struct hlist_node *p, *q; 129 struct hlist_node *p, *q;
130 struct mpath_node *gate;
121 int i; 131 int i;
122 132
123 mesh_hash = tbl->hash_buckets; 133 mesh_hash = tbl->hash_buckets;
@@ -129,6 +139,17 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
129 } 139 }
130 spin_unlock_bh(&tbl->hashwlock[i]); 140 spin_unlock_bh(&tbl->hashwlock[i]);
131 } 141 }
142 if (free_leafs) {
143 spin_lock_bh(&tbl->gates_lock);
144 hlist_for_each_entry_safe(gate, p, q,
145 tbl->known_gates, list) {
146 hlist_del(&gate->list);
147 kfree(gate);
148 }
149 kfree(tbl->known_gates);
150 spin_unlock_bh(&tbl->gates_lock);
151 }
152
132 __mesh_table_free(tbl); 153 __mesh_table_free(tbl);
133} 154}
134 155
@@ -146,6 +167,7 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
146 newtbl->free_node = oldtbl->free_node; 167 newtbl->free_node = oldtbl->free_node;
147 newtbl->mean_chain_len = oldtbl->mean_chain_len; 168 newtbl->mean_chain_len = oldtbl->mean_chain_len;
148 newtbl->copy_node = oldtbl->copy_node; 169 newtbl->copy_node = oldtbl->copy_node;
170 newtbl->known_gates = oldtbl->known_gates;
149 atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries)); 171 atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries));
150 172
151 oldhash = oldtbl->hash_buckets; 173 oldhash = oldtbl->hash_buckets;
@@ -205,6 +227,111 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
205 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags); 227 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
206} 228}
207 229
230static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
231 struct mesh_path *gate_mpath)
232{
233 struct ieee80211_hdr *hdr;
234 struct ieee80211s_hdr *mshdr;
235 int mesh_hdrlen, hdrlen;
236 char *next_hop;
237
238 hdr = (struct ieee80211_hdr *) skb->data;
239 hdrlen = ieee80211_hdrlen(hdr->frame_control);
240 mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
241
242 if (!(mshdr->flags & MESH_FLAGS_AE)) {
243 /* size of the fixed part of the mesh header */
244 mesh_hdrlen = 6;
245
246 /* make room for the two extended addresses */
247 skb_push(skb, 2 * ETH_ALEN);
248 memmove(skb->data, hdr, hdrlen + mesh_hdrlen);
249
250 hdr = (struct ieee80211_hdr *) skb->data;
251
252 /* we preserve the previous mesh header and only add
253 * the new addreses */
254 mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
255 mshdr->flags = MESH_FLAGS_AE_A5_A6;
256 memcpy(mshdr->eaddr1, hdr->addr3, ETH_ALEN);
257 memcpy(mshdr->eaddr2, hdr->addr4, ETH_ALEN);
258 }
259
260 /* update next hop */
261 hdr = (struct ieee80211_hdr *) skb->data;
262 rcu_read_lock();
263 next_hop = rcu_dereference(gate_mpath->next_hop)->sta.addr;
264 memcpy(hdr->addr1, next_hop, ETH_ALEN);
265 rcu_read_unlock();
266 memcpy(hdr->addr3, dst_addr, ETH_ALEN);
267}
268
269/**
270 *
271 * mesh_path_move_to_queue - Move or copy frames from one mpath queue to another
272 *
273 * This function is used to transfer or copy frames from an unresolved mpath to
274 * a gate mpath. The function also adds the Address Extension field and
275 * updates the next hop.
276 *
277 * If a frame already has an Address Extension field, only the next hop and
278 * destination addresses are updated.
279 *
280 * The gate mpath must be an active mpath with a valid mpath->next_hop.
281 *
282 * @mpath: An active mpath the frames will be sent to (i.e. the gate)
283 * @from_mpath: The failed mpath
284 * @copy: When true, copy all the frames to the new mpath queue. When false,
285 * move them.
286 */
287static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
288 struct mesh_path *from_mpath,
289 bool copy)
290{
291 struct sk_buff *skb, *cp_skb = NULL;
292 struct sk_buff_head gateq, failq;
293 unsigned long flags;
294 int num_skbs;
295
296 BUG_ON(gate_mpath == from_mpath);
297 BUG_ON(!gate_mpath->next_hop);
298
299 __skb_queue_head_init(&gateq);
300 __skb_queue_head_init(&failq);
301
302 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
303 skb_queue_splice_init(&from_mpath->frame_queue, &failq);
304 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);
305
306 num_skbs = skb_queue_len(&failq);
307
308 while (num_skbs--) {
309 skb = __skb_dequeue(&failq);
310 if (copy)
311 cp_skb = skb_copy(skb, GFP_ATOMIC);
312
313 prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
314 __skb_queue_tail(&gateq, skb);
315
316 if (copy && cp_skb)
317 __skb_queue_tail(&failq, cp_skb);
318 }
319
320 spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags);
321 skb_queue_splice(&gateq, &gate_mpath->frame_queue);
322 mpath_dbg("Mpath queue for gate %pM has %d frames\n",
323 gate_mpath->dst,
324 skb_queue_len(&gate_mpath->frame_queue));
325 spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags);
326
327 if (!copy)
328 return;
329
330 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
331 skb_queue_splice(&failq, &from_mpath->frame_queue);
332 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);
333}
334
208 335
209/** 336/**
210 * mesh_path_lookup - look up a path in the mesh path table 337 * mesh_path_lookup - look up a path in the mesh path table
@@ -304,6 +431,109 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
304 return NULL; 431 return NULL;
305} 432}
306 433
434static void mesh_gate_node_reclaim(struct rcu_head *rp)
435{
436 struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
437 kfree(node);
438}
439
440/**
441 * mesh_gate_add - mark mpath as path to a mesh gate and add to known_gates
442 * @mesh_tbl: table which contains known_gates list
443 * @mpath: mpath to known mesh gate
444 *
445 * Returns: 0 on success
446 *
447 */
448static int mesh_gate_add(struct mesh_table *tbl, struct mesh_path *mpath)
449{
450 struct mpath_node *gate, *new_gate;
451 struct hlist_node *n;
452 int err;
453
454 rcu_read_lock();
455 tbl = rcu_dereference(tbl);
456
457 hlist_for_each_entry_rcu(gate, n, tbl->known_gates, list)
458 if (gate->mpath == mpath) {
459 err = -EEXIST;
460 goto err_rcu;
461 }
462
463 new_gate = kzalloc(sizeof(struct mpath_node), GFP_ATOMIC);
464 if (!new_gate) {
465 err = -ENOMEM;
466 goto err_rcu;
467 }
468
469 mpath->is_gate = true;
470 mpath->sdata->u.mesh.num_gates++;
471 new_gate->mpath = mpath;
472 spin_lock_bh(&tbl->gates_lock);
473 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
474 spin_unlock_bh(&tbl->gates_lock);
475 rcu_read_unlock();
476 mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n",
477 mpath->sdata->name, mpath->dst,
478 mpath->sdata->u.mesh.num_gates);
479 return 0;
480err_rcu:
481 rcu_read_unlock();
482 return err;
483}
484
485/**
486 * mesh_gate_del - remove a mesh gate from the list of known gates
487 * @tbl: table which holds our list of known gates
488 * @mpath: gate mpath
489 *
490 * Returns: 0 on success
491 *
492 * Locking: must be called inside rcu_read_lock() section
493 */
494static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
495{
496 struct mpath_node *gate;
497 struct hlist_node *p, *q;
498
499 tbl = rcu_dereference(tbl);
500
501 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list)
502 if (gate->mpath == mpath) {
503 spin_lock_bh(&tbl->gates_lock);
504 hlist_del_rcu(&gate->list);
505 call_rcu(&gate->rcu, mesh_gate_node_reclaim);
506 spin_unlock_bh(&tbl->gates_lock);
507 mpath->sdata->u.mesh.num_gates--;
508 mpath->is_gate = false;
509 mpath_dbg("Mesh path (%s): Deleted gate: %pM. "
510 "%d known gates\n", mpath->sdata->name,
511 mpath->dst, mpath->sdata->u.mesh.num_gates);
512 break;
513 }
514
515 return 0;
516}
517
518/**
519 *
520 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
521 * @mpath: gate path to add to table
522 */
523int mesh_path_add_gate(struct mesh_path *mpath)
524{
525 return mesh_gate_add(mesh_paths, mpath);
526}
527
528/**
529 * mesh_gate_num - number of gates known to this interface
530 * @sdata: subif data
531 */
532int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
533{
534 return sdata->u.mesh.num_gates;
535}
536
307/** 537/**
308 * mesh_path_add - allocate and add a new path to the mesh path table 538 * mesh_path_add - allocate and add a new path to the mesh path table
309 * @addr: destination address of the path (ETH_ALEN length) 539 * @addr: destination address of the path (ETH_ALEN length)
@@ -481,6 +711,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
481 new_mpath->flags = 0; 711 new_mpath->flags = 0;
482 skb_queue_head_init(&new_mpath->frame_queue); 712 skb_queue_head_init(&new_mpath->frame_queue);
483 new_node->mpath = new_mpath; 713 new_node->mpath = new_mpath;
714 init_timer(&new_mpath->timer);
484 new_mpath->exp_time = jiffies; 715 new_mpath->exp_time = jiffies;
485 spin_lock_init(&new_mpath->state_lock); 716 spin_lock_init(&new_mpath->state_lock);
486 717
@@ -539,6 +770,7 @@ void mesh_plink_broken(struct sta_info *sta)
539 struct hlist_node *p; 770 struct hlist_node *p;
540 struct ieee80211_sub_if_data *sdata = sta->sdata; 771 struct ieee80211_sub_if_data *sdata = sta->sdata;
541 int i; 772 int i;
773 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
542 774
543 rcu_read_lock(); 775 rcu_read_lock();
544 tbl = rcu_dereference(mesh_paths); 776 tbl = rcu_dereference(mesh_paths);
@@ -553,8 +785,7 @@ void mesh_plink_broken(struct sta_info *sta)
553 spin_unlock_bh(&mpath->state_lock); 785 spin_unlock_bh(&mpath->state_lock);
554 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 786 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
555 mpath->dst, cpu_to_le32(mpath->sn), 787 mpath->dst, cpu_to_le32(mpath->sn),
556 cpu_to_le16(PERR_RCODE_DEST_UNREACH), 788 reason, bcast, sdata);
557 bcast, sdata);
558 } else 789 } else
559 spin_unlock_bh(&mpath->state_lock); 790 spin_unlock_bh(&mpath->state_lock);
560 } 791 }
@@ -647,12 +878,14 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
647 mpath = node->mpath; 878 mpath = node->mpath;
648 if (mpath->sdata == sdata && 879 if (mpath->sdata == sdata &&
649 memcmp(addr, mpath->dst, ETH_ALEN) == 0) { 880 memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
650 spin_lock(&mpath->state_lock); 881 spin_lock_bh(&mpath->state_lock);
882 if (mpath->is_gate)
883 mesh_gate_del(tbl, mpath);
651 mpath->flags |= MESH_PATH_RESOLVING; 884 mpath->flags |= MESH_PATH_RESOLVING;
652 hlist_del_rcu(&node->list); 885 hlist_del_rcu(&node->list);
653 call_rcu(&node->rcu, mesh_path_node_reclaim); 886 call_rcu(&node->rcu, mesh_path_node_reclaim);
654 atomic_dec(&tbl->entries); 887 atomic_dec(&tbl->entries);
655 spin_unlock(&mpath->state_lock); 888 spin_unlock_bh(&mpath->state_lock);
656 goto enddel; 889 goto enddel;
657 } 890 }
658 } 891 }
@@ -681,6 +914,58 @@ void mesh_path_tx_pending(struct mesh_path *mpath)
681} 914}
682 915
683/** 916/**
917 * mesh_path_send_to_gates - sends pending frames to all known mesh gates
918 *
919 * @mpath: mesh path whose queue will be emptied
920 *
921 * If there is only one gate, the frames are transferred from the failed mpath
922 * queue to that gate's queue. If there are more than one gates, the frames
923 * are copied from each gate to the next. After frames are copied, the
924 * mpath queues are emptied onto the transmission queue.
925 */
926int mesh_path_send_to_gates(struct mesh_path *mpath)
927{
928 struct ieee80211_sub_if_data *sdata = mpath->sdata;
929 struct hlist_node *n;
930 struct mesh_table *tbl;
931 struct mesh_path *from_mpath = mpath;
932 struct mpath_node *gate = NULL;
933 bool copy = false;
934 struct hlist_head *known_gates;
935
936 rcu_read_lock();
937 tbl = rcu_dereference(mesh_paths);
938 known_gates = tbl->known_gates;
939 rcu_read_unlock();
940
941 if (!known_gates)
942 return -EHOSTUNREACH;
943
944 hlist_for_each_entry_rcu(gate, n, known_gates, list) {
945 if (gate->mpath->sdata != sdata)
946 continue;
947
948 if (gate->mpath->flags & MESH_PATH_ACTIVE) {
949 mpath_dbg("Forwarding to %pM\n", gate->mpath->dst);
950 mesh_path_move_to_queue(gate->mpath, from_mpath, copy);
951 from_mpath = gate->mpath;
952 copy = true;
953 } else {
954 mpath_dbg("Not forwarding %p\n", gate->mpath);
955 mpath_dbg("flags %x\n", gate->mpath->flags);
956 }
957 }
958
959 hlist_for_each_entry_rcu(gate, n, known_gates, list)
960 if (gate->mpath->sdata == sdata) {
961 mpath_dbg("Sending to %pM\n", gate->mpath->dst);
962 mesh_path_tx_pending(gate->mpath);
963 }
964
965 return (from_mpath == mpath) ? -EHOSTUNREACH : 0;
966}
967
968/**
684 * mesh_path_discard_frame - discard a frame whose path could not be resolved 969 * mesh_path_discard_frame - discard a frame whose path could not be resolved
685 * 970 *
686 * @skb: frame to discard 971 * @skb: frame to discard
@@ -699,6 +984,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
699 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 984 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
700 struct mesh_path *mpath; 985 struct mesh_path *mpath;
701 u32 sn = 0; 986 u32 sn = 0;
987 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
702 988
703 if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) { 989 if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) {
704 u8 *ra, *da; 990 u8 *ra, *da;
@@ -709,8 +995,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
709 if (mpath) 995 if (mpath)
710 sn = ++mpath->sn; 996 sn = ++mpath->sn;
711 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data, 997 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data,
712 cpu_to_le32(sn), 998 cpu_to_le32(sn), reason, ra, sdata);
713 cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata);
714 } 999 }
715 1000
716 kfree_skb(skb); 1001 kfree_skb(skb);
@@ -728,8 +1013,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
728{ 1013{
729 struct sk_buff *skb; 1014 struct sk_buff *skb;
730 1015
731 while ((skb = skb_dequeue(&mpath->frame_queue)) && 1016 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
732 (mpath->flags & MESH_PATH_ACTIVE))
733 mesh_path_discard_frame(skb, mpath->sdata); 1017 mesh_path_discard_frame(skb, mpath->sdata);
734} 1018}
735 1019
@@ -797,6 +1081,9 @@ int mesh_pathtbl_init(void)
797 tbl_path->free_node = &mesh_path_node_free; 1081 tbl_path->free_node = &mesh_path_node_free;
798 tbl_path->copy_node = &mesh_path_node_copy; 1082 tbl_path->copy_node = &mesh_path_node_copy;
799 tbl_path->mean_chain_len = MEAN_CHAIN_LEN; 1083 tbl_path->mean_chain_len = MEAN_CHAIN_LEN;
1084 tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
1085 INIT_HLIST_HEAD(tbl_path->known_gates);
1086
800 1087
801 tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); 1088 tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
802 if (!tbl_mpp) { 1089 if (!tbl_mpp) {
@@ -806,6 +1093,8 @@ int mesh_pathtbl_init(void)
806 tbl_mpp->free_node = &mesh_path_node_free; 1093 tbl_mpp->free_node = &mesh_path_node_free;
807 tbl_mpp->copy_node = &mesh_path_node_copy; 1094 tbl_mpp->copy_node = &mesh_path_node_copy;
808 tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; 1095 tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN;
1096 tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
1097 INIT_HLIST_HEAD(tbl_mpp->known_gates);
809 1098
810 /* Need no locking since this is during init */ 1099 /* Need no locking since this is during init */
811 RCU_INIT_POINTER(mesh_paths, tbl_path); 1100 RCU_INIT_POINTER(mesh_paths, tbl_path);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f4adc0917888..1a00d0f701c3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,35 +19,18 @@
19#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) 19#define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
20#endif 20#endif
21 21
22#define PLINK_GET_LLID(p) (p + 4) 22#define PLINK_GET_LLID(p) (p + 2)
23#define PLINK_GET_PLID(p) (p + 6) 23#define PLINK_GET_PLID(p) (p + 4)
24 24
25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
26 jiffies + HZ * t / 1000)) 26 jiffies + HZ * t / 1000))
27 27
28/* Peer link cancel reasons, all subject to ANA approval */
29#define MESH_LINK_CANCELLED 2
30#define MESH_MAX_NEIGHBORS 3
31#define MESH_CAPABILITY_POLICY_VIOLATION 4
32#define MESH_CLOSE_RCVD 5
33#define MESH_MAX_RETRIES 6
34#define MESH_CONFIRM_TIMEOUT 7
35#define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS 8
36#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9
37#define MESH_SECURITY_FAILED_VERIFICATION 10
38
39#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries) 28#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
40#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout) 29#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
41#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout) 30#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
42#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) 31#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 32#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44 33
45enum plink_frame_type {
46 PLINK_OPEN = 1,
47 PLINK_CONFIRM,
48 PLINK_CLOSE
49};
50
51enum plink_event { 34enum plink_event {
52 PLINK_UNDEFINED, 35 PLINK_UNDEFINED,
53 OPN_ACPT, 36 OPN_ACPT,
@@ -157,16 +140,16 @@ void mesh_plink_deactivate(struct sta_info *sta)
157} 140}
158 141
159static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 142static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, 143 enum ieee80211_self_protected_actioncode action,
161 __le16 reason) { 144 u8 *da, __le16 llid, __le16 plid, __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 145 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 146 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.ie_len); 147 sdata->u.mesh.ie_len);
165 struct ieee80211_mgmt *mgmt; 148 struct ieee80211_mgmt *mgmt;
166 bool include_plid = false; 149 bool include_plid = false;
167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 150 int ie_len = 4;
151 u16 peering_proto = 0;
168 u8 *pos; 152 u8 *pos;
169 int ie_len;
170 153
171 if (!skb) 154 if (!skb)
172 return -1; 155 return -1;
@@ -175,63 +158,75 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
175 * common action part (1) 158 * common action part (1)
176 */ 159 */
177 mgmt = (struct ieee80211_mgmt *) 160 mgmt = (struct ieee80211_mgmt *)
178 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action)); 161 skb_put(skb, 25 + sizeof(mgmt->u.action.u.self_prot));
179 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action)); 162 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.self_prot));
180 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 163 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
181 IEEE80211_STYPE_ACTION); 164 IEEE80211_STYPE_ACTION);
182 memcpy(mgmt->da, da, ETH_ALEN); 165 memcpy(mgmt->da, da, ETH_ALEN);
183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 166 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
184 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 167 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
185 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 168 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
186 mgmt->u.action.u.plink_action.action_code = action; 169 mgmt->u.action.u.self_prot.action_code = action;
187 170
188 if (action == PLINK_CLOSE) 171 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
189 mgmt->u.action.u.plink_action.aux = reason; 172 /* capability info */
190 else { 173 pos = skb_put(skb, 2);
191 mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0); 174 memset(pos, 0, 2);
192 if (action == PLINK_CONFIRM) { 175 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
193 pos = skb_put(skb, 4); 176 /* AID */
194 /* two-byte status code followed by two-byte AID */ 177 pos = skb_put(skb, 2);
195 memset(pos, 0, 2);
196 memcpy(pos + 2, &plid, 2); 178 memcpy(pos + 2, &plid, 2);
197 } 179 }
198 mesh_mgmt_ies_add(skb, sdata); 180 if (mesh_add_srates_ie(skb, sdata) ||
181 mesh_add_ext_srates_ie(skb, sdata) ||
182 mesh_add_rsn_ie(skb, sdata) ||
183 mesh_add_meshid_ie(skb, sdata) ||
184 mesh_add_meshconf_ie(skb, sdata))
185 return -1;
186 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
187 if (mesh_add_meshid_ie(skb, sdata))
188 return -1;
199 } 189 }
200 190
201 /* Add Peer Link Management element */ 191 /* Add Mesh Peering Management element */
202 switch (action) { 192 switch (action) {
203 case PLINK_OPEN: 193 case WLAN_SP_MESH_PEERING_OPEN:
204 ie_len = 6;
205 break; 194 break;
206 case PLINK_CONFIRM: 195 case WLAN_SP_MESH_PEERING_CONFIRM:
207 ie_len = 8; 196 ie_len += 2;
208 include_plid = true; 197 include_plid = true;
209 break; 198 break;
210 case PLINK_CLOSE: 199 case WLAN_SP_MESH_PEERING_CLOSE:
211 default: 200 if (plid) {
212 if (!plid) 201 ie_len += 2;
213 ie_len = 8;
214 else {
215 ie_len = 10;
216 include_plid = true; 202 include_plid = true;
217 } 203 }
204 ie_len += 2; /* reason code */
218 break; 205 break;
206 default:
207 return -EINVAL;
219 } 208 }
220 209
210 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
211 return -ENOMEM;
212
221 pos = skb_put(skb, 2 + ie_len); 213 pos = skb_put(skb, 2 + ie_len);
222 *pos++ = WLAN_EID_PEER_LINK; 214 *pos++ = WLAN_EID_PEER_MGMT;
223 *pos++ = ie_len; 215 *pos++ = ie_len;
224 memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto)); 216 memcpy(pos, &peering_proto, 2);
225 pos += 4; 217 pos += 2;
226 memcpy(pos, &llid, 2); 218 memcpy(pos, &llid, 2);
219 pos += 2;
227 if (include_plid) { 220 if (include_plid) {
228 pos += 2;
229 memcpy(pos, &plid, 2); 221 memcpy(pos, &plid, 2);
230 }
231 if (action == PLINK_CLOSE) {
232 pos += 2; 222 pos += 2;
223 }
224 if (action == WLAN_SP_MESH_PEERING_CLOSE) {
233 memcpy(pos, &reason, 2); 225 memcpy(pos, &reason, 2);
226 pos += 2;
234 } 227 }
228 if (mesh_add_vendor_ies(skb, sdata))
229 return -1;
235 230
236 ieee80211_tx_skb(sdata, skb); 231 ieee80211_tx_skb(sdata, skb);
237 return 0; 232 return 0;
@@ -322,21 +317,21 @@ static void mesh_plink_timer(unsigned long data)
322 ++sta->plink_retries; 317 ++sta->plink_retries;
323 mod_plink_timer(sta, sta->plink_timeout); 318 mod_plink_timer(sta, sta->plink_timeout);
324 spin_unlock_bh(&sta->lock); 319 spin_unlock_bh(&sta->lock);
325 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 320 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
326 0, 0); 321 sta->sta.addr, llid, 0, 0);
327 break; 322 break;
328 } 323 }
329 reason = cpu_to_le16(MESH_MAX_RETRIES); 324 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
330 /* fall through on else */ 325 /* fall through on else */
331 case NL80211_PLINK_CNF_RCVD: 326 case NL80211_PLINK_CNF_RCVD:
332 /* confirm timer */ 327 /* confirm timer */
333 if (!reason) 328 if (!reason)
334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 329 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
335 sta->plink_state = NL80211_PLINK_HOLDING; 330 sta->plink_state = NL80211_PLINK_HOLDING;
336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 331 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
337 spin_unlock_bh(&sta->lock); 332 spin_unlock_bh(&sta->lock);
338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, 333 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
339 reason); 334 sta->sta.addr, llid, plid, reason);
340 break; 335 break;
341 case NL80211_PLINK_HOLDING: 336 case NL80211_PLINK_HOLDING:
342 /* holding timer */ 337 /* holding timer */
@@ -396,7 +391,7 @@ int mesh_plink_open(struct sta_info *sta)
396 mpl_dbg("Mesh plink: starting establishment with %pM\n", 391 mpl_dbg("Mesh plink: starting establishment with %pM\n",
397 sta->sta.addr); 392 sta->sta.addr);
398 393
399 return mesh_plink_frame_tx(sdata, PLINK_OPEN, 394 return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
400 sta->sta.addr, llid, 0, 0); 395 sta->sta.addr, llid, 0, 0);
401} 396}
402 397
@@ -422,7 +417,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
422 struct ieee802_11_elems elems; 417 struct ieee802_11_elems elems;
423 struct sta_info *sta; 418 struct sta_info *sta;
424 enum plink_event event; 419 enum plink_event event;
425 enum plink_frame_type ftype; 420 enum ieee80211_self_protected_actioncode ftype;
426 size_t baselen; 421 size_t baselen;
427 bool deactivated, matches_local = true; 422 bool deactivated, matches_local = true;
428 u8 ie_len; 423 u8 ie_len;
@@ -449,14 +444,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
449 return; 444 return;
450 } 445 }
451 446
452 baseaddr = mgmt->u.action.u.plink_action.variable; 447 baseaddr = mgmt->u.action.u.self_prot.variable;
453 baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt; 448 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
454 if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) { 449 if (mgmt->u.action.u.self_prot.action_code ==
450 WLAN_SP_MESH_PEERING_CONFIRM) {
455 baseaddr += 4; 451 baseaddr += 4;
456 baselen += 4; 452 baselen += 4;
457 } 453 }
458 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 454 ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
459 if (!elems.peer_link) { 455 if (!elems.peering) {
460 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 456 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
461 return; 457 return;
462 } 458 }
@@ -466,31 +462,34 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
466 return; 462 return;
467 } 463 }
468 464
469 ftype = mgmt->u.action.u.plink_action.action_code; 465 ftype = mgmt->u.action.u.self_prot.action_code;
470 ie_len = elems.peer_link_len; 466 ie_len = elems.peering_len;
471 if ((ftype == PLINK_OPEN && ie_len != 6) || 467 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
472 (ftype == PLINK_CONFIRM && ie_len != 8) || 468 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
473 (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) { 469 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
470 && ie_len != 8)) {
474 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", 471 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
475 ftype, ie_len); 472 ftype, ie_len);
476 return; 473 return;
477 } 474 }
478 475
479 if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { 476 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
477 (!elems.mesh_id || !elems.mesh_config)) {
480 mpl_dbg("Mesh plink: missing necessary ie\n"); 478 mpl_dbg("Mesh plink: missing necessary ie\n");
481 return; 479 return;
482 } 480 }
483 /* Note the lines below are correct, the llid in the frame is the plid 481 /* Note the lines below are correct, the llid in the frame is the plid
484 * from the point of view of this host. 482 * from the point of view of this host.
485 */ 483 */
486 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2); 484 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
487 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10)) 485 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
488 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 486 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
487 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
489 488
490 rcu_read_lock(); 489 rcu_read_lock();
491 490
492 sta = sta_info_get(sdata, mgmt->sa); 491 sta = sta_info_get(sdata, mgmt->sa);
493 if (!sta && ftype != PLINK_OPEN) { 492 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
494 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 493 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
495 rcu_read_unlock(); 494 rcu_read_unlock();
496 return; 495 return;
@@ -509,30 +508,30 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
509 508
510 /* Now we will figure out the appropriate event... */ 509 /* Now we will figure out the appropriate event... */
511 event = PLINK_UNDEFINED; 510 event = PLINK_UNDEFINED;
512 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 511 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
512 (!mesh_matches_local(&elems, sdata))) {
513 matches_local = false; 513 matches_local = false;
514 switch (ftype) { 514 switch (ftype) {
515 case PLINK_OPEN: 515 case WLAN_SP_MESH_PEERING_OPEN:
516 event = OPN_RJCT; 516 event = OPN_RJCT;
517 break; 517 break;
518 case PLINK_CONFIRM: 518 case WLAN_SP_MESH_PEERING_CONFIRM:
519 event = CNF_RJCT; 519 event = CNF_RJCT;
520 break; 520 break;
521 case PLINK_CLOSE: 521 default:
522 /* avoid warning */
523 break; 522 break;
524 } 523 }
525 } 524 }
526 525
527 if (!sta && !matches_local) { 526 if (!sta && !matches_local) {
528 rcu_read_unlock(); 527 rcu_read_unlock();
529 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 528 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
530 llid = 0; 529 llid = 0;
531 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, 530 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
532 plid, reason); 531 mgmt->sa, llid, plid, reason);
533 return; 532 return;
534 } else if (!sta) { 533 } else if (!sta) {
535 /* ftype == PLINK_OPEN */ 534 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
536 u32 rates; 535 u32 rates;
537 536
538 rcu_read_unlock(); 537 rcu_read_unlock();
@@ -557,21 +556,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
557 } else if (matches_local) { 556 } else if (matches_local) {
558 spin_lock_bh(&sta->lock); 557 spin_lock_bh(&sta->lock);
559 switch (ftype) { 558 switch (ftype) {
560 case PLINK_OPEN: 559 case WLAN_SP_MESH_PEERING_OPEN:
561 if (!mesh_plink_free_count(sdata) || 560 if (!mesh_plink_free_count(sdata) ||
562 (sta->plid && sta->plid != plid)) 561 (sta->plid && sta->plid != plid))
563 event = OPN_IGNR; 562 event = OPN_IGNR;
564 else 563 else
565 event = OPN_ACPT; 564 event = OPN_ACPT;
566 break; 565 break;
567 case PLINK_CONFIRM: 566 case WLAN_SP_MESH_PEERING_CONFIRM:
568 if (!mesh_plink_free_count(sdata) || 567 if (!mesh_plink_free_count(sdata) ||
569 (sta->llid != llid || sta->plid != plid)) 568 (sta->llid != llid || sta->plid != plid))
570 event = CNF_IGNR; 569 event = CNF_IGNR;
571 else 570 else
572 event = CNF_ACPT; 571 event = CNF_ACPT;
573 break; 572 break;
574 case PLINK_CLOSE: 573 case WLAN_SP_MESH_PEERING_CLOSE:
575 if (sta->plink_state == NL80211_PLINK_ESTAB) 574 if (sta->plink_state == NL80211_PLINK_ESTAB)
576 /* Do not check for llid or plid. This does not 575 /* Do not check for llid or plid. This does not
577 * follow the standard but since multiple plinks 576 * follow the standard but since multiple plinks
@@ -620,10 +619,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
620 sta->llid = llid; 619 sta->llid = llid;
621 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 620 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
622 spin_unlock_bh(&sta->lock); 621 spin_unlock_bh(&sta->lock);
623 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 622 mesh_plink_frame_tx(sdata,
624 0, 0); 623 WLAN_SP_MESH_PEERING_OPEN,
625 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, 624 sta->sta.addr, llid, 0, 0);
626 llid, plid, 0); 625 mesh_plink_frame_tx(sdata,
626 WLAN_SP_MESH_PEERING_CONFIRM,
627 sta->sta.addr, llid, plid, 0);
627 break; 628 break;
628 default: 629 default:
629 spin_unlock_bh(&sta->lock); 630 spin_unlock_bh(&sta->lock);
@@ -635,10 +636,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
635 switch (event) { 636 switch (event) {
636 case OPN_RJCT: 637 case OPN_RJCT:
637 case CNF_RJCT: 638 case CNF_RJCT:
638 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 639 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
639 case CLS_ACPT: 640 case CLS_ACPT:
640 if (!reason) 641 if (!reason)
641 reason = cpu_to_le16(MESH_CLOSE_RCVD); 642 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
642 sta->reason = reason; 643 sta->reason = reason;
643 sta->plink_state = NL80211_PLINK_HOLDING; 644 sta->plink_state = NL80211_PLINK_HOLDING;
644 if (!mod_plink_timer(sta, 645 if (!mod_plink_timer(sta,
@@ -647,8 +648,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
647 648
648 llid = sta->llid; 649 llid = sta->llid;
649 spin_unlock_bh(&sta->lock); 650 spin_unlock_bh(&sta->lock);
650 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 651 mesh_plink_frame_tx(sdata,
651 plid, reason); 652 WLAN_SP_MESH_PEERING_CLOSE,
653 sta->sta.addr, llid, plid, reason);
652 break; 654 break;
653 case OPN_ACPT: 655 case OPN_ACPT:
654 /* retry timer is left untouched */ 656 /* retry timer is left untouched */
@@ -656,8 +658,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
656 sta->plid = plid; 658 sta->plid = plid;
657 llid = sta->llid; 659 llid = sta->llid;
658 spin_unlock_bh(&sta->lock); 660 spin_unlock_bh(&sta->lock);
659 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 661 mesh_plink_frame_tx(sdata,
660 plid, 0); 662 WLAN_SP_MESH_PEERING_CONFIRM,
663 sta->sta.addr, llid, plid, 0);
661 break; 664 break;
662 case CNF_ACPT: 665 case CNF_ACPT:
663 sta->plink_state = NL80211_PLINK_CNF_RCVD; 666 sta->plink_state = NL80211_PLINK_CNF_RCVD;
@@ -677,10 +680,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
677 switch (event) { 680 switch (event) {
678 case OPN_RJCT: 681 case OPN_RJCT:
679 case CNF_RJCT: 682 case CNF_RJCT:
680 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 683 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
681 case CLS_ACPT: 684 case CLS_ACPT:
682 if (!reason) 685 if (!reason)
683 reason = cpu_to_le16(MESH_CLOSE_RCVD); 686 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
684 sta->reason = reason; 687 sta->reason = reason;
685 sta->plink_state = NL80211_PLINK_HOLDING; 688 sta->plink_state = NL80211_PLINK_HOLDING;
686 if (!mod_plink_timer(sta, 689 if (!mod_plink_timer(sta,
@@ -689,14 +692,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
689 692
690 llid = sta->llid; 693 llid = sta->llid;
691 spin_unlock_bh(&sta->lock); 694 spin_unlock_bh(&sta->lock);
692 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 695 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
693 plid, reason); 696 sta->sta.addr, llid, plid, reason);
694 break; 697 break;
695 case OPN_ACPT: 698 case OPN_ACPT:
696 llid = sta->llid; 699 llid = sta->llid;
697 spin_unlock_bh(&sta->lock); 700 spin_unlock_bh(&sta->lock);
698 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 701 mesh_plink_frame_tx(sdata,
699 plid, 0); 702 WLAN_SP_MESH_PEERING_CONFIRM,
703 sta->sta.addr, llid, plid, 0);
700 break; 704 break;
701 case CNF_ACPT: 705 case CNF_ACPT:
702 del_timer(&sta->plink_timer); 706 del_timer(&sta->plink_timer);
@@ -717,10 +721,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
717 switch (event) { 721 switch (event) {
718 case OPN_RJCT: 722 case OPN_RJCT:
719 case CNF_RJCT: 723 case CNF_RJCT:
720 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 724 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
721 case CLS_ACPT: 725 case CLS_ACPT:
722 if (!reason) 726 if (!reason)
723 reason = cpu_to_le16(MESH_CLOSE_RCVD); 727 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
724 sta->reason = reason; 728 sta->reason = reason;
725 sta->plink_state = NL80211_PLINK_HOLDING; 729 sta->plink_state = NL80211_PLINK_HOLDING;
726 if (!mod_plink_timer(sta, 730 if (!mod_plink_timer(sta,
@@ -729,8 +733,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
729 733
730 llid = sta->llid; 734 llid = sta->llid;
731 spin_unlock_bh(&sta->lock); 735 spin_unlock_bh(&sta->lock);
732 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 736 mesh_plink_frame_tx(sdata,
733 plid, reason); 737 WLAN_SP_MESH_PEERING_CLOSE,
738 sta->sta.addr, llid, plid, reason);
734 break; 739 break;
735 case OPN_ACPT: 740 case OPN_ACPT:
736 del_timer(&sta->plink_timer); 741 del_timer(&sta->plink_timer);
@@ -740,8 +745,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
740 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 745 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
741 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 746 mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
742 sta->sta.addr); 747 sta->sta.addr);
743 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 748 mesh_plink_frame_tx(sdata,
744 plid, 0); 749 WLAN_SP_MESH_PEERING_CONFIRM,
750 sta->sta.addr, llid, plid, 0);
745 break; 751 break;
746 default: 752 default:
747 spin_unlock_bh(&sta->lock); 753 spin_unlock_bh(&sta->lock);
@@ -752,7 +758,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
752 case NL80211_PLINK_ESTAB: 758 case NL80211_PLINK_ESTAB:
753 switch (event) { 759 switch (event) {
754 case CLS_ACPT: 760 case CLS_ACPT:
755 reason = cpu_to_le16(MESH_CLOSE_RCVD); 761 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
756 sta->reason = reason; 762 sta->reason = reason;
757 deactivated = __mesh_plink_deactivate(sta); 763 deactivated = __mesh_plink_deactivate(sta);
758 sta->plink_state = NL80211_PLINK_HOLDING; 764 sta->plink_state = NL80211_PLINK_HOLDING;
@@ -761,14 +767,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
761 spin_unlock_bh(&sta->lock); 767 spin_unlock_bh(&sta->lock);
762 if (deactivated) 768 if (deactivated)
763 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 769 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
764 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 770 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
765 plid, reason); 771 sta->sta.addr, llid, plid, reason);
766 break; 772 break;
767 case OPN_ACPT: 773 case OPN_ACPT:
768 llid = sta->llid; 774 llid = sta->llid;
769 spin_unlock_bh(&sta->lock); 775 spin_unlock_bh(&sta->lock);
770 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 776 mesh_plink_frame_tx(sdata,
771 plid, 0); 777 WLAN_SP_MESH_PEERING_CONFIRM,
778 sta->sta.addr, llid, plid, 0);
772 break; 779 break;
773 default: 780 default:
774 spin_unlock_bh(&sta->lock); 781 spin_unlock_bh(&sta->lock);
@@ -790,8 +797,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
790 llid = sta->llid; 797 llid = sta->llid;
791 reason = sta->reason; 798 reason = sta->reason;
792 spin_unlock_bh(&sta->lock); 799 spin_unlock_bh(&sta->lock);
793 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, 800 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
794 llid, plid, reason); 801 sta->sta.addr, llid, plid, reason);
795 break; 802 break;
796 default: 803 default:
797 spin_unlock_bh(&sta->lock); 804 spin_unlock_bh(&sta->lock);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d6470c7fd6ce..60a6f273cd30 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1482,10 +1482,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1482 1482
1483 ifmgd->aid = aid; 1483 ifmgd->aid = aid;
1484 1484
1485 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); 1485 mutex_lock(&sdata->local->sta_mtx);
1486 if (!sta) { 1486 /*
1487 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1487 * station info was already allocated and inserted before
1488 " the AP\n", sdata->name); 1488 * the association and should be available to us
1489 */
1490 sta = sta_info_get_rx(sdata, cbss->bssid);
1491 if (WARN_ON(!sta)) {
1492 mutex_unlock(&sdata->local->sta_mtx);
1489 return false; 1493 return false;
1490 } 1494 }
1491 1495
@@ -1556,7 +1560,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1556 if (elems.wmm_param) 1560 if (elems.wmm_param)
1557 set_sta_flags(sta, WLAN_STA_WME); 1561 set_sta_flags(sta, WLAN_STA_WME);
1558 1562
1559 err = sta_info_insert(sta); 1563 /* sta_info_reinsert will also unlock the mutex lock */
1564 err = sta_info_reinsert(sta);
1560 sta = NULL; 1565 sta = NULL;
1561 if (err) { 1566 if (err) {
1562 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1567 printk(KERN_DEBUG "%s: failed to insert STA entry for"
@@ -2429,6 +2434,32 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2429 return 0; 2434 return 0;
2430} 2435}
2431 2436
2437/* create and insert a dummy station entry */
2438static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
2439 u8 *bssid) {
2440 struct sta_info *sta;
2441 int err;
2442
2443 sta = sta_info_alloc(sdata, bssid, GFP_KERNEL);
2444 if (!sta) {
2445 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
2446 " the AP\n", sdata->name);
2447 return -ENOMEM;
2448 }
2449
2450 sta->dummy = true;
2451
2452 err = sta_info_insert(sta);
2453 sta = NULL;
2454 if (err) {
2455 printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
2456 " the AP (error %d)\n", sdata->name, err);
2457 return err;
2458 }
2459
2460 return 0;
2461}
2462
2432static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, 2463static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2433 struct sk_buff *skb) 2464 struct sk_buff *skb)
2434{ 2465{
@@ -2436,9 +2467,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2436 struct ieee80211_mgmt *mgmt; 2467 struct ieee80211_mgmt *mgmt;
2437 struct ieee80211_rx_status *rx_status; 2468 struct ieee80211_rx_status *rx_status;
2438 struct ieee802_11_elems elems; 2469 struct ieee802_11_elems elems;
2470 struct cfg80211_bss *cbss = wk->assoc.bss;
2439 u16 status; 2471 u16 status;
2440 2472
2441 if (!skb) { 2473 if (!skb) {
2474 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2442 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); 2475 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
2443 goto destroy; 2476 goto destroy;
2444 } 2477 }
@@ -2468,12 +2501,16 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2468 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { 2501 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
2469 mutex_unlock(&wk->sdata->u.mgd.mtx); 2502 mutex_unlock(&wk->sdata->u.mgd.mtx);
2470 /* oops -- internal error -- send timeout for now */ 2503 /* oops -- internal error -- send timeout for now */
2504 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2471 cfg80211_send_assoc_timeout(wk->sdata->dev, 2505 cfg80211_send_assoc_timeout(wk->sdata->dev,
2472 wk->filter_ta); 2506 wk->filter_ta);
2473 return WORK_DONE_DESTROY; 2507 return WORK_DONE_DESTROY;
2474 } 2508 }
2475 2509
2476 mutex_unlock(&wk->sdata->u.mgd.mtx); 2510 mutex_unlock(&wk->sdata->u.mgd.mtx);
2511 } else {
2512 /* assoc failed - destroy the dummy station entry */
2513 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2477 } 2514 }
2478 2515
2479 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); 2516 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
@@ -2492,7 +2529,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2492 struct ieee80211_bss *bss = (void *)req->bss->priv; 2529 struct ieee80211_bss *bss = (void *)req->bss->priv;
2493 struct ieee80211_work *wk; 2530 struct ieee80211_work *wk;
2494 const u8 *ssid; 2531 const u8 *ssid;
2495 int i; 2532 int i, err;
2496 2533
2497 mutex_lock(&ifmgd->mtx); 2534 mutex_lock(&ifmgd->mtx);
2498 if (ifmgd->associated) { 2535 if (ifmgd->associated) {
@@ -2517,6 +2554,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2517 if (!wk) 2554 if (!wk)
2518 return -ENOMEM; 2555 return -ENOMEM;
2519 2556
2557 /*
2558 * create a dummy station info entry in order
2559 * to start accepting incoming EAPOL packets from the station
2560 */
2561 err = ieee80211_pre_assoc(sdata, req->bss->bssid);
2562 if (err) {
2563 kfree(wk);
2564 return err;
2565 }
2566
2520 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 2567 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2521 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 2568 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2522 2569
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fe2c2a717793..f45fd2fedc24 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -850,8 +850,21 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
850 ieee80211_is_pspoll(hdr->frame_control)) && 850 ieee80211_is_pspoll(hdr->frame_control)) &&
851 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 851 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
852 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 852 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
853 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) 853 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
854 if (rx->sta && rx->sta->dummy &&
855 ieee80211_is_data_present(hdr->frame_control)) {
856 u16 ethertype;
857 u8 *payload;
858
859 payload = rx->skb->data +
860 ieee80211_hdrlen(hdr->frame_control);
861 ethertype = (payload[6] << 8) | payload[7];
862 if (cpu_to_be16(ethertype) ==
863 rx->sdata->control_port_protocol)
864 return RX_CONTINUE;
865 }
854 return RX_DROP_MONITOR; 866 return RX_DROP_MONITOR;
867 }
855 868
856 return RX_CONTINUE; 869 return RX_CONTINUE;
857} 870}
@@ -2220,12 +2233,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2220 goto handled; 2233 goto handled;
2221 } 2234 }
2222 break; 2235 break;
2236 case WLAN_CATEGORY_SELF_PROTECTED:
2237 switch (mgmt->u.action.u.self_prot.action_code) {
2238 case WLAN_SP_MESH_PEERING_OPEN:
2239 case WLAN_SP_MESH_PEERING_CLOSE:
2240 case WLAN_SP_MESH_PEERING_CONFIRM:
2241 if (!ieee80211_vif_is_mesh(&sdata->vif))
2242 goto invalid;
2243 if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
2244 /* userspace handles this frame */
2245 break;
2246 goto queue;
2247 case WLAN_SP_MGK_INFORM:
2248 case WLAN_SP_MGK_ACK:
2249 if (!ieee80211_vif_is_mesh(&sdata->vif))
2250 goto invalid;
2251 break;
2252 }
2253 break;
2223 case WLAN_CATEGORY_MESH_ACTION: 2254 case WLAN_CATEGORY_MESH_ACTION:
2224 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2255 if (!ieee80211_vif_is_mesh(&sdata->vif))
2225 break; 2256 break;
2226 goto queue; 2257 if (mesh_action_is_path_sel(mgmt) &&
2227 case WLAN_CATEGORY_MESH_PATH_SEL: 2258 (!mesh_path_sel_is_hwmp(sdata)))
2228 if (!mesh_path_sel_is_hwmp(sdata))
2229 break; 2259 break;
2230 goto queue; 2260 goto queue;
2231 } 2261 }
@@ -2686,7 +2716,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2686 } else if (!ieee80211_bssid_match(bssid, 2716 } else if (!ieee80211_bssid_match(bssid,
2687 sdata->vif.addr)) { 2717 sdata->vif.addr)) {
2688 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2718 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
2689 !ieee80211_is_beacon(hdr->frame_control)) 2719 !ieee80211_is_beacon(hdr->frame_control) &&
2720 !(ieee80211_is_action(hdr->frame_control) &&
2721 sdata->vif.p2p))
2690 return 0; 2722 return 0;
2691 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2723 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2692 } 2724 }
@@ -2791,7 +2823,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2791 if (ieee80211_is_data(fc)) { 2823 if (ieee80211_is_data(fc)) {
2792 prev_sta = NULL; 2824 prev_sta = NULL;
2793 2825
2794 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2826 for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
2795 if (!prev_sta) { 2827 if (!prev_sta) {
2796 prev_sta = sta; 2828 prev_sta = sta;
2797 continue; 2829 continue;
@@ -2835,7 +2867,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2835 continue; 2867 continue;
2836 } 2868 }
2837 2869
2838 rx.sta = sta_info_get_bss(prev, hdr->addr2); 2870 rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
2839 rx.sdata = prev; 2871 rx.sdata = prev;
2840 ieee80211_prepare_and_rx_handle(&rx, skb, false); 2872 ieee80211_prepare_and_rx_handle(&rx, skb, false);
2841 2873
@@ -2843,7 +2875,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2843 } 2875 }
2844 2876
2845 if (prev) { 2877 if (prev) {
2846 rx.sta = sta_info_get_bss(prev, hdr->addr2); 2878 rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
2847 rx.sdata = prev; 2879 rx.sdata = prev;
2848 2880
2849 if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) 2881 if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 0bdbf3b8f28b..6bc17fb80ee9 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -100,6 +100,27 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
100 lockdep_is_held(&local->sta_lock) || 100 lockdep_is_held(&local->sta_lock) ||
101 lockdep_is_held(&local->sta_mtx)); 101 lockdep_is_held(&local->sta_mtx));
102 while (sta) { 102 while (sta) {
103 if (sta->sdata == sdata && !sta->dummy &&
104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
105 break;
106 sta = rcu_dereference_check(sta->hnext,
107 lockdep_is_held(&local->sta_lock) ||
108 lockdep_is_held(&local->sta_mtx));
109 }
110 return sta;
111}
112
113/* get a station info entry even if it is a dummy station*/
114struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
115 const u8 *addr)
116{
117 struct ieee80211_local *local = sdata->local;
118 struct sta_info *sta;
119
120 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
121 lockdep_is_held(&local->sta_lock) ||
122 lockdep_is_held(&local->sta_mtx));
123 while (sta) {
103 if (sta->sdata == sdata && 124 if (sta->sdata == sdata &&
104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 125 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
105 break; 126 break;
@@ -126,6 +147,32 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
126 while (sta) { 147 while (sta) {
127 if ((sta->sdata == sdata || 148 if ((sta->sdata == sdata ||
128 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && 149 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
150 !sta->dummy &&
151 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
152 break;
153 sta = rcu_dereference_check(sta->hnext,
154 lockdep_is_held(&local->sta_lock) ||
155 lockdep_is_held(&local->sta_mtx));
156 }
157 return sta;
158}
159
160/*
161 * Get sta info either from the specified interface
162 * or from one of its vlans (including dummy stations)
163 */
164struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
165 const u8 *addr)
166{
167 struct ieee80211_local *local = sdata->local;
168 struct sta_info *sta;
169
170 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
171 lockdep_is_held(&local->sta_lock) ||
172 lockdep_is_held(&local->sta_mtx));
173 while (sta) {
174 if ((sta->sdata == sdata ||
175 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
129 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 176 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
130 break; 177 break;
131 sta = rcu_dereference_check(sta->hnext, 178 sta = rcu_dereference_check(sta->hnext,
@@ -280,7 +327,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
280 return sta; 327 return sta;
281} 328}
282 329
283static int sta_info_finish_insert(struct sta_info *sta, bool async) 330static int sta_info_finish_insert(struct sta_info *sta,
331 bool async, bool dummy_reinsert)
284{ 332{
285 struct ieee80211_local *local = sta->local; 333 struct ieee80211_local *local = sta->local;
286 struct ieee80211_sub_if_data *sdata = sta->sdata; 334 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -290,51 +338,58 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
290 338
291 lockdep_assert_held(&local->sta_mtx); 339 lockdep_assert_held(&local->sta_mtx);
292 340
293 /* notify driver */ 341 if (!sta->dummy || dummy_reinsert) {
294 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 342 /* notify driver */
295 sdata = container_of(sdata->bss, 343 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
296 struct ieee80211_sub_if_data, 344 sdata = container_of(sdata->bss,
297 u.ap); 345 struct ieee80211_sub_if_data,
298 err = drv_sta_add(local, sdata, &sta->sta); 346 u.ap);
299 if (err) { 347 err = drv_sta_add(local, sdata, &sta->sta);
300 if (!async) 348 if (err) {
301 return err; 349 if (!async)
302 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to driver (%d)" 350 return err;
303 " - keeping it anyway.\n", 351 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
304 sdata->name, sta->sta.addr, err); 352 "driver (%d) - keeping it anyway.\n",
305 } else { 353 sdata->name, sta->sta.addr, err);
306 sta->uploaded = true; 354 } else {
355 sta->uploaded = true;
307#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 356#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
308 if (async) 357 if (async)
309 wiphy_debug(local->hw.wiphy, 358 wiphy_debug(local->hw.wiphy,
310 "Finished adding IBSS STA %pM\n", 359 "Finished adding IBSS STA %pM\n",
311 sta->sta.addr); 360 sta->sta.addr);
312#endif 361#endif
362 }
363
364 sdata = sta->sdata;
313 } 365 }
314 366
315 sdata = sta->sdata; 367 if (!dummy_reinsert) {
368 if (!async) {
369 local->num_sta++;
370 local->sta_generation++;
371 smp_mb();
316 372
317 if (!async) { 373 /* make the station visible */
318 local->num_sta++; 374 spin_lock_irqsave(&local->sta_lock, flags);
319 local->sta_generation++; 375 sta_info_hash_add(local, sta);
320 smp_mb(); 376 spin_unlock_irqrestore(&local->sta_lock, flags);
377 }
321 378
322 /* make the station visible */ 379 list_add(&sta->list, &local->sta_list);
323 spin_lock_irqsave(&local->sta_lock, flags); 380 } else {
324 sta_info_hash_add(local, sta); 381 sta->dummy = false;
325 spin_unlock_irqrestore(&local->sta_lock, flags);
326 } 382 }
327 383
328 list_add(&sta->list, &local->sta_list); 384 if (!sta->dummy) {
329 385 ieee80211_sta_debugfs_add(sta);
330 ieee80211_sta_debugfs_add(sta); 386 rate_control_add_sta_debugfs(sta);
331 rate_control_add_sta_debugfs(sta);
332
333 memset(&sinfo, 0, sizeof(sinfo));
334 sinfo.filled = 0;
335 sinfo.generation = local->sta_generation;
336 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
337 387
388 memset(&sinfo, 0, sizeof(sinfo));
389 sinfo.filled = 0;
390 sinfo.generation = local->sta_generation;
391 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
392 }
338 393
339 return 0; 394 return 0;
340} 395}
@@ -351,7 +406,7 @@ static void sta_info_finish_pending(struct ieee80211_local *local)
351 list_del(&sta->list); 406 list_del(&sta->list);
352 spin_unlock_irqrestore(&local->sta_lock, flags); 407 spin_unlock_irqrestore(&local->sta_lock, flags);
353 408
354 sta_info_finish_insert(sta, true); 409 sta_info_finish_insert(sta, true, false);
355 410
356 spin_lock_irqsave(&local->sta_lock, flags); 411 spin_lock_irqsave(&local->sta_lock, flags);
357 } 412 }
@@ -368,106 +423,117 @@ static void sta_info_finish_work(struct work_struct *work)
368 mutex_unlock(&local->sta_mtx); 423 mutex_unlock(&local->sta_mtx);
369} 424}
370 425
371int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) 426static int sta_info_insert_check(struct sta_info *sta)
372{ 427{
373 struct ieee80211_local *local = sta->local;
374 struct ieee80211_sub_if_data *sdata = sta->sdata; 428 struct ieee80211_sub_if_data *sdata = sta->sdata;
375 unsigned long flags;
376 int err = 0;
377 429
378 /* 430 /*
379 * Can't be a WARN_ON because it can be triggered through a race: 431 * Can't be a WARN_ON because it can be triggered through a race:
380 * something inserts a STA (on one CPU) without holding the RTNL 432 * something inserts a STA (on one CPU) without holding the RTNL
381 * and another CPU turns off the net device. 433 * and another CPU turns off the net device.
382 */ 434 */
383 if (unlikely(!ieee80211_sdata_running(sdata))) { 435 if (unlikely(!ieee80211_sdata_running(sdata)))
384 err = -ENETDOWN; 436 return -ENETDOWN;
385 rcu_read_lock();
386 goto out_free;
387 }
388 437
389 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 || 438 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 ||
390 is_multicast_ether_addr(sta->sta.addr))) { 439 is_multicast_ether_addr(sta->sta.addr)))
391 err = -EINVAL; 440 return -EINVAL;
441
442 return 0;
443}
444
445static int sta_info_insert_ibss(struct sta_info *sta) __acquires(RCU)
446{
447 struct ieee80211_local *local = sta->local;
448 struct ieee80211_sub_if_data *sdata = sta->sdata;
449 unsigned long flags;
450
451 spin_lock_irqsave(&local->sta_lock, flags);
452 /* check if STA exists already */
453 if (sta_info_get_bss_rx(sdata, sta->sta.addr)) {
454 spin_unlock_irqrestore(&local->sta_lock, flags);
392 rcu_read_lock(); 455 rcu_read_lock();
393 goto out_free; 456 return -EEXIST;
394 } 457 }
395 458
396 /* 459 local->num_sta++;
397 * In ad-hoc mode, we sometimes need to insert stations 460 local->sta_generation++;
398 * from tasklet context from the RX path. To avoid races, 461 smp_mb();
399 * always do so in that case -- see the comment below. 462 sta_info_hash_add(local, sta);
400 */
401 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
402 spin_lock_irqsave(&local->sta_lock, flags);
403 /* check if STA exists already */
404 if (sta_info_get_bss(sdata, sta->sta.addr)) {
405 spin_unlock_irqrestore(&local->sta_lock, flags);
406 rcu_read_lock();
407 err = -EEXIST;
408 goto out_free;
409 }
410
411 local->num_sta++;
412 local->sta_generation++;
413 smp_mb();
414 sta_info_hash_add(local, sta);
415 463
416 list_add_tail(&sta->list, &local->sta_pending_list); 464 list_add_tail(&sta->list, &local->sta_pending_list);
417 465
418 rcu_read_lock(); 466 rcu_read_lock();
419 spin_unlock_irqrestore(&local->sta_lock, flags); 467 spin_unlock_irqrestore(&local->sta_lock, flags);
420 468
421#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 469#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
422 wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n", 470 wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n",
423 sta->sta.addr); 471 sta->sta.addr);
424#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 472#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
425 473
426 ieee80211_queue_work(&local->hw, &local->sta_finish_work); 474 ieee80211_queue_work(&local->hw, &local->sta_finish_work);
427 475
428 return 0; 476 return 0;
429 } 477}
478
479/*
480 * should be called with sta_mtx locked
481 * this function replaces the mutex lock
482 * with a RCU lock
483 */
484static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU)
485{
486 struct ieee80211_local *local = sta->local;
487 struct ieee80211_sub_if_data *sdata = sta->sdata;
488 unsigned long flags;
489 struct sta_info *exist_sta;
490 bool dummy_reinsert = false;
491 int err = 0;
492
493 lockdep_assert_held(&local->sta_mtx);
430 494
431 /* 495 /*
432 * On first glance, this will look racy, because the code 496 * On first glance, this will look racy, because the code
433 * below this point, which inserts a station with sleeping, 497 * in this function, which inserts a station with sleeping,
434 * unlocks the sta_lock between checking existence in the 498 * unlocks the sta_lock between checking existence in the
435 * hash table and inserting into it. 499 * hash table and inserting into it.
436 * 500 *
437 * However, it is not racy against itself because it keeps 501 * However, it is not racy against itself because it keeps
438 * the mutex locked. It still seems to race against the 502 * the mutex locked.
439 * above code that atomically inserts the station... That,
440 * however, is not true because the above code can only
441 * be invoked for IBSS interfaces, and the below code will
442 * not be -- and the two do not race against each other as
443 * the hash table also keys off the interface.
444 */ 503 */
445 504
446 might_sleep();
447
448 mutex_lock(&local->sta_mtx);
449
450 spin_lock_irqsave(&local->sta_lock, flags); 505 spin_lock_irqsave(&local->sta_lock, flags);
451 /* check if STA exists already */ 506 /*
452 if (sta_info_get_bss(sdata, sta->sta.addr)) { 507 * check if STA exists already.
453 spin_unlock_irqrestore(&local->sta_lock, flags); 508 * only accept a scenario of a second call to sta_info_insert_non_ibss
454 mutex_unlock(&local->sta_mtx); 509 * with a dummy station entry that was inserted earlier
455 rcu_read_lock(); 510 * in that case - assume that the dummy station flag should
456 err = -EEXIST; 511 * be removed.
457 goto out_free; 512 */
513 exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
514 if (exist_sta) {
515 if (exist_sta == sta && sta->dummy) {
516 dummy_reinsert = true;
517 } else {
518 spin_unlock_irqrestore(&local->sta_lock, flags);
519 mutex_unlock(&local->sta_mtx);
520 rcu_read_lock();
521 return -EEXIST;
522 }
458 } 523 }
459 524
460 spin_unlock_irqrestore(&local->sta_lock, flags); 525 spin_unlock_irqrestore(&local->sta_lock, flags);
461 526
462 err = sta_info_finish_insert(sta, false); 527 err = sta_info_finish_insert(sta, false, dummy_reinsert);
463 if (err) { 528 if (err) {
464 mutex_unlock(&local->sta_mtx); 529 mutex_unlock(&local->sta_mtx);
465 rcu_read_lock(); 530 rcu_read_lock();
466 goto out_free; 531 return err;
467 } 532 }
468 533
469#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 534#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
470 wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); 535 wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
536 sta->dummy ? "dummy " : "", sta->sta.addr);
471#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 537#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
472 538
473 /* move reference to rcu-protected */ 539 /* move reference to rcu-protected */
@@ -478,6 +544,51 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
478 mesh_accept_plinks_update(sdata); 544 mesh_accept_plinks_update(sdata);
479 545
480 return 0; 546 return 0;
547}
548
549int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
550{
551 struct ieee80211_local *local = sta->local;
552 struct ieee80211_sub_if_data *sdata = sta->sdata;
553 int err = 0;
554
555 err = sta_info_insert_check(sta);
556 if (err) {
557 rcu_read_lock();
558 goto out_free;
559 }
560
561 /*
562 * In ad-hoc mode, we sometimes need to insert stations
563 * from tasklet context from the RX path. To avoid races,
564 * always do so in that case -- see the comment below.
565 */
566 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
567 err = sta_info_insert_ibss(sta);
568 if (err)
569 goto out_free;
570
571 return 0;
572 }
573
574 /*
575 * It might seem that the function called below is in race against
576 * the function call above that atomically inserts the station... That,
577 * however, is not true because the above code can only
578 * be invoked for IBSS interfaces, and the below code will
579 * not be -- and the two do not race against each other as
580 * the hash table also keys off the interface.
581 */
582
583 might_sleep();
584
585 mutex_lock(&local->sta_mtx);
586
587 err = sta_info_insert_non_ibss(sta);
588 if (err)
589 goto out_free;
590
591 return 0;
481 out_free: 592 out_free:
482 BUG_ON(!err); 593 BUG_ON(!err);
483 __sta_info_free(local, sta); 594 __sta_info_free(local, sta);
@@ -493,6 +604,25 @@ int sta_info_insert(struct sta_info *sta)
493 return err; 604 return err;
494} 605}
495 606
607/* Caller must hold sta->local->sta_mtx */
608int sta_info_reinsert(struct sta_info *sta)
609{
610 struct ieee80211_local *local = sta->local;
611 int err = 0;
612
613 err = sta_info_insert_check(sta);
614 if (err) {
615 mutex_unlock(&local->sta_mtx);
616 return err;
617 }
618
619 might_sleep();
620
621 err = sta_info_insert_non_ibss(sta);
622 rcu_read_unlock();
623 return err;
624}
625
496static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 626static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
497{ 627{
498 /* 628 /*
@@ -733,7 +863,7 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
733 int ret; 863 int ret;
734 864
735 mutex_lock(&sdata->local->sta_mtx); 865 mutex_lock(&sdata->local->sta_mtx);
736 sta = sta_info_get(sdata, addr); 866 sta = sta_info_get_rx(sdata, addr);
737 ret = __sta_info_destroy(sta); 867 ret = __sta_info_destroy(sta);
738 mutex_unlock(&sdata->local->sta_mtx); 868 mutex_unlock(&sdata->local->sta_mtx);
739 869
@@ -747,7 +877,7 @@ int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
747 int ret; 877 int ret;
748 878
749 mutex_lock(&sdata->local->sta_mtx); 879 mutex_lock(&sdata->local->sta_mtx);
750 sta = sta_info_get_bss(sdata, addr); 880 sta = sta_info_get_bss_rx(sdata, addr);
751 ret = __sta_info_destroy(sta); 881 ret = __sta_info_destroy(sta);
752 mutex_unlock(&sdata->local->sta_mtx); 882 mutex_unlock(&sdata->local->sta_mtx);
753 883
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 28beb78e601e..e9eb565506da 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -238,10 +238,12 @@ struct sta_ampdu_mlme {
238 * @plink_timer: peer link watch timer 238 * @plink_timer: peer link watch timer
239 * @plink_timer_was_running: used by suspend/resume to restore timers 239 * @plink_timer_was_running: used by suspend/resume to restore timers
240 * @debugfs: debug filesystem info 240 * @debugfs: debug filesystem info
241 * @sta: station information we share with the driver
242 * @dead: set to true when sta is unlinked 241 * @dead: set to true when sta is unlinked
243 * @uploaded: set to true when sta is uploaded to the driver 242 * @uploaded: set to true when sta is uploaded to the driver
244 * @lost_packets: number of consecutive lost packets 243 * @lost_packets: number of consecutive lost packets
244 * @dummy: indicate a dummy station created for receiving
245 * EAP frames before association
246 * @sta: station information we share with the driver
245 */ 247 */
246struct sta_info { 248struct sta_info {
247 /* General information, mostly static */ 249 /* General information, mostly static */
@@ -336,6 +338,9 @@ struct sta_info {
336 338
337 unsigned int lost_packets; 339 unsigned int lost_packets;
338 340
341 /* should be right in front of sta to be in the same cache line */
342 bool dummy;
343
339 /* keep last! */ 344 /* keep last! */
340 struct ieee80211_sta sta; 345 struct ieee80211_sta sta;
341}; 346};
@@ -436,9 +441,15 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
436struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, 441struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
437 const u8 *addr); 442 const u8 *addr);
438 443
444struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
445 const u8 *addr);
446
439struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, 447struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
440 const u8 *addr); 448 const u8 *addr);
441 449
450struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
451 const u8 *addr);
452
442static inline 453static inline
443void for_each_sta_info_type_check(struct ieee80211_local *local, 454void for_each_sta_info_type_check(struct ieee80211_local *local,
444 const u8 *addr, 455 const u8 *addr,
@@ -459,6 +470,22 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
459 _sta = nxt, \ 470 _sta = nxt, \
460 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ 471 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
461 ) \ 472 ) \
473 /* run code only if address matches and it's not a dummy sta */ \
474 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 && \
475 !_sta->dummy)
476
477#define for_each_sta_info_rx(local, _addr, _sta, nxt) \
478 for ( /* initialise loop */ \
479 _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
480 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \
481 /* typecheck */ \
482 for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
483 /* continue condition */ \
484 _sta; \
485 /* advance loop */ \
486 _sta = nxt, \
487 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
488 ) \
462 /* compare address and run code only if it matches */ \ 489 /* compare address and run code only if it matches */ \
463 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) 490 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
464 491
@@ -484,6 +511,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
484int sta_info_insert(struct sta_info *sta); 511int sta_info_insert(struct sta_info *sta);
485int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); 512int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
486int sta_info_insert_atomic(struct sta_info *sta); 513int sta_info_insert_atomic(struct sta_info *sta);
514int sta_info_reinsert(struct sta_info *sta);
487 515
488int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, 516int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
489 const u8 *addr); 517 const u8 *addr);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index a89cca3491b4..e51bd2a1a073 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -187,6 +187,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
187 int rates_idx = -1; 187 int rates_idx = -1;
188 bool send_to_cooked; 188 bool send_to_cooked;
189 bool acked; 189 bool acked;
190 struct ieee80211_bar *bar;
191 u16 tid;
190 192
191 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 193 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
192 if (info->status.rates[i].idx < 0) { 194 if (info->status.rates[i].idx < 0) {
@@ -243,6 +245,22 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
243 tid, ssn); 245 tid, ssn);
244 } 246 }
245 247
248 if (!acked && ieee80211_is_back_req(fc)) {
249 /*
250 * BAR failed, let's tear down the BA session as a
251 * last resort as some STAs (Intel 5100 on Windows)
252 * can get stuck when the BA window isn't flushed
253 * correctly.
254 */
255 bar = (struct ieee80211_bar *) skb->data;
256 if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
257 tid = (bar->control &
258 IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
259 IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
260 ieee80211_stop_tx_ba_session(&sta->sta, tid);
261 }
262 }
263
246 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { 264 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
247 ieee80211_handle_filtered_frame(local, sta, skb); 265 ieee80211_handle_filtered_frame(local, sta, skb);
248 rcu_read_unlock(); 266 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 69fd494f32f9..01072639666f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2295,13 +2295,23 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2295 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 2295 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
2296 mgmt->u.beacon.beacon_int = 2296 mgmt->u.beacon.beacon_int =
2297 cpu_to_le16(sdata->vif.bss_conf.beacon_int); 2297 cpu_to_le16(sdata->vif.bss_conf.beacon_int);
2298 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ 2298 mgmt->u.beacon.capab_info |= cpu_to_le16(
2299 sdata->u.mesh.security ? WLAN_CAPABILITY_PRIVACY : 0);
2299 2300
2300 pos = skb_put(skb, 2); 2301 pos = skb_put(skb, 2);
2301 *pos++ = WLAN_EID_SSID; 2302 *pos++ = WLAN_EID_SSID;
2302 *pos++ = 0x0; 2303 *pos++ = 0x0;
2303 2304
2304 mesh_mgmt_ies_add(skb, sdata); 2305 if (mesh_add_srates_ie(skb, sdata) ||
2306 mesh_add_ds_params_ie(skb, sdata) ||
2307 mesh_add_ext_srates_ie(skb, sdata) ||
2308 mesh_add_rsn_ie(skb, sdata) ||
2309 mesh_add_meshid_ie(skb, sdata) ||
2310 mesh_add_meshconf_ie(skb, sdata) ||
2311 mesh_add_vendor_ies(skb, sdata)) {
2312 pr_err("o11s: couldn't add ies!\n");
2313 goto out;
2314 }
2305 } else { 2315 } else {
2306 WARN_ON(1); 2316 WARN_ON(1);
2307 goto out; 2317 goto out;