aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-15 08:40:31 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 09:46:37 -0500
commitbf7cd94dcc71682cd6af4a9028f95307b7db41c5 (patch)
tree66b4573619eaebf52c0a298969a9756eb0059266 /net/mac80211
parent93c78c5debeb9c7101ecc73347d4730c26a98c05 (diff)
mac80211: clean up mesh code
There's various code with strange indentation, questionable loop and locking constructs, etc. The bigger change is moving the "sdata" argument to the first argument of all functions, like all other mac80211 functions that have one. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c115
-rw-r--r--net/mac80211/mesh.h105
-rw-r--r--net/mac80211/mesh_hwmp.c68
-rw-r--r--net/mac80211/mesh_pathtbl.c89
-rw-r--r--net/mac80211/mesh_plink.c36
-rw-r--r--net/mac80211/mesh_sync.c47
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/tx.c26
10 files changed, 252 insertions, 263 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 179dcbd8be1c..09d96a8f6c2c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1500,13 +1500,13 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
1500 return -ENOENT; 1500 return -ENOENT;
1501 } 1501 }
1502 1502
1503 err = mesh_path_add(dst, sdata); 1503 err = mesh_path_add(sdata, dst);
1504 if (err) { 1504 if (err) {
1505 rcu_read_unlock(); 1505 rcu_read_unlock();
1506 return err; 1506 return err;
1507 } 1507 }
1508 1508
1509 mpath = mesh_path_lookup(dst, sdata); 1509 mpath = mesh_path_lookup(sdata, dst);
1510 if (!mpath) { 1510 if (!mpath) {
1511 rcu_read_unlock(); 1511 rcu_read_unlock();
1512 return -ENXIO; 1512 return -ENXIO;
@@ -1518,12 +1518,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
1518} 1518}
1519 1519
1520static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 1520static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
1521 u8 *dst) 1521 u8 *dst)
1522{ 1522{
1523 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1523 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1524 1524
1525 if (dst) 1525 if (dst)
1526 return mesh_path_del(dst, sdata); 1526 return mesh_path_del(sdata, dst);
1527 1527
1528 mesh_path_flush_by_iface(sdata); 1528 mesh_path_flush_by_iface(sdata);
1529 return 0; 1529 return 0;
@@ -1547,7 +1547,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
1547 return -ENOENT; 1547 return -ENOENT;
1548 } 1548 }
1549 1549
1550 mpath = mesh_path_lookup(dst, sdata); 1550 mpath = mesh_path_lookup(sdata, dst);
1551 if (!mpath) { 1551 if (!mpath) {
1552 rcu_read_unlock(); 1552 rcu_read_unlock();
1553 return -ENOENT; 1553 return -ENOENT;
@@ -1611,7 +1611,7 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
1611 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1611 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1612 1612
1613 rcu_read_lock(); 1613 rcu_read_lock();
1614 mpath = mesh_path_lookup(dst, sdata); 1614 mpath = mesh_path_lookup(sdata, dst);
1615 if (!mpath) { 1615 if (!mpath) {
1616 rcu_read_unlock(); 1616 rcu_read_unlock();
1617 return -ENOENT; 1617 return -ENOENT;
@@ -1632,7 +1632,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1632 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1632 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1633 1633
1634 rcu_read_lock(); 1634 rcu_read_lock();
1635 mpath = mesh_path_lookup_by_idx(idx, sdata); 1635 mpath = mesh_path_lookup_by_idx(sdata, idx);
1636 if (!mpath) { 1636 if (!mpath) {
1637 rcu_read_unlock(); 1637 rcu_read_unlock();
1638 return -ENOENT; 1638 return -ENOENT;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f9747689d604..d0dd11153a6c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1173,8 +1173,7 @@ static void __exit ieee80211_exit(void)
1173 rc80211_minstrel_ht_exit(); 1173 rc80211_minstrel_ht_exit();
1174 rc80211_minstrel_exit(); 1174 rc80211_minstrel_exit();
1175 1175
1176 if (mesh_allocated) 1176 ieee80211s_stop();
1177 ieee80211s_stop();
1178 1177
1179 ieee80211_iface_exit(); 1178 ieee80211_iface_exit();
1180 1179
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a77d40ed4e61..b0223326d9cd 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -17,7 +17,7 @@
17#define TMR_RUNNING_MP 1 17#define TMR_RUNNING_MP 1
18#define TMR_RUNNING_MPR 2 18#define TMR_RUNNING_MPR 2
19 19
20int mesh_allocated; 20static int mesh_allocated;
21static struct kmem_cache *rm_cache; 21static struct kmem_cache *rm_cache;
22 22
23bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) 23bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
@@ -36,6 +36,8 @@ void ieee80211s_init(void)
36 36
37void ieee80211s_stop(void) 37void ieee80211s_stop(void)
38{ 38{
39 if (!mesh_allocated)
40 return;
39 mesh_pathtbl_unregister(); 41 mesh_pathtbl_unregister();
40 kmem_cache_destroy(rm_cache); 42 kmem_cache_destroy(rm_cache);
41} 43}
@@ -90,24 +92,22 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
90 (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && 92 (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) &&
91 (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && 93 (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) &&
92 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) 94 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
93 goto mismatch; 95 return false;
94 96
95 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), 97 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata),
96 &basic_rates); 98 &basic_rates);
97 99
98 if (sdata->vif.bss_conf.basic_rates != basic_rates) 100 if (sdata->vif.bss_conf.basic_rates != basic_rates)
99 goto mismatch; 101 return false;
100 102
101 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 103 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
102 ie->ht_operation, &sta_chan_def); 104 ie->ht_operation, &sta_chan_def);
103 105
104 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef, 106 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
105 &sta_chan_def)) 107 &sta_chan_def))
106 goto mismatch; 108 return false;
107 109
108 return true; 110 return true;
109mismatch:
110 return false;
111} 111}
112 112
113/** 113/**
@@ -118,7 +118,7 @@ mismatch:
118bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) 118bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
119{ 119{
120 return (ie->mesh_config->meshconf_cap & 120 return (ie->mesh_config->meshconf_cap &
121 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; 121 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
122} 122}
123 123
124/** 124/**
@@ -196,11 +196,12 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
196 if (!sdata->u.mesh.rmc) 196 if (!sdata->u.mesh.rmc)
197 return; 197 return;
198 198
199 for (i = 0; i < RMC_BUCKETS; i++) 199 for (i = 0; i < RMC_BUCKETS; i++) {
200 list_for_each_entry_safe(p, n, &rmc->bucket[i], list) { 200 list_for_each_entry_safe(p, n, &rmc->bucket[i], list) {
201 list_del(&p->list); 201 list_del(&p->list);
202 kmem_cache_free(rm_cache, p); 202 kmem_cache_free(rm_cache, p);
203 } 203 }
204 }
204 205
205 kfree(rmc); 206 kfree(rmc);
206 sdata->u.mesh.rmc = NULL; 207 sdata->u.mesh.rmc = NULL;
@@ -209,6 +210,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
209/** 210/**
210 * mesh_rmc_check - Check frame in recent multicast cache and add if absent. 211 * mesh_rmc_check - Check frame in recent multicast cache and add if absent.
211 * 212 *
213 * @sdata: interface
212 * @sa: source address 214 * @sa: source address
213 * @mesh_hdr: mesh_header 215 * @mesh_hdr: mesh_header
214 * 216 *
@@ -218,8 +220,8 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
218 * received this frame lately. If the frame is not in the cache, it is added to 220 * received this frame lately. If the frame is not in the cache, it is added to
219 * it. 221 * it.
220 */ 222 */
221int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, 223int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
222 struct ieee80211_sub_if_data *sdata) 224 const u8 *sa, struct ieee80211s_hdr *mesh_hdr)
223{ 225{
224 struct mesh_rmc *rmc = sdata->u.mesh.rmc; 226 struct mesh_rmc *rmc = sdata->u.mesh.rmc;
225 u32 seqnum = 0; 227 u32 seqnum = 0;
@@ -233,12 +235,11 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
233 list_for_each_entry_safe(p, n, &rmc->bucket[idx], list) { 235 list_for_each_entry_safe(p, n, &rmc->bucket[idx], list) {
234 ++entries; 236 ++entries;
235 if (time_after(jiffies, p->exp_time) || 237 if (time_after(jiffies, p->exp_time) ||
236 (entries == RMC_QUEUE_MAX_LEN)) { 238 entries == RMC_QUEUE_MAX_LEN) {
237 list_del(&p->list); 239 list_del(&p->list);
238 kmem_cache_free(rm_cache, p); 240 kmem_cache_free(rm_cache, p);
239 --entries; 241 --entries;
240 } else if ((seqnum == p->seqnum) && 242 } else if ((seqnum == p->seqnum) && ether_addr_equal(sa, p->sa))
241 (ether_addr_equal(sa, p->sa)))
242 return -1; 243 return -1;
243 } 244 }
244 245
@@ -253,8 +254,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
253 return 0; 254 return 0;
254} 255}
255 256
256int 257int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
257mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 258 struct sk_buff *skb)
258{ 259{
259 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 260 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
260 u8 *pos, neighbors; 261 u8 *pos, neighbors;
@@ -285,19 +286,18 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
285 /* Mesh capability */ 286 /* Mesh capability */
286 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; 287 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
287 *pos |= ifmsh->accepting_plinks ? 288 *pos |= ifmsh->accepting_plinks ?
288 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 289 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
289 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */ 290 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */
290 *pos |= ifmsh->ps_peers_deep_sleep ? 291 *pos |= ifmsh->ps_peers_deep_sleep ?
291 IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL : 0x00; 292 IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL : 0x00;
292 *pos++ |= ifmsh->adjusting_tbtt ? 293 *pos++ |= ifmsh->adjusting_tbtt ?
293 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00; 294 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
294 *pos++ = 0x00; 295 *pos++ = 0x00;
295 296
296 return 0; 297 return 0;
297} 298}
298 299
299int 300int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
300mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
301{ 301{
302 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 302 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
303 u8 *pos; 303 u8 *pos;
@@ -314,8 +314,8 @@ mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
314 return 0; 314 return 0;
315} 315}
316 316
317int mesh_add_awake_window_ie(struct sk_buff *skb, 317static int mesh_add_awake_window_ie(struct ieee80211_sub_if_data *sdata,
318 struct ieee80211_sub_if_data *sdata) 318 struct sk_buff *skb)
319{ 319{
320 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 320 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
321 u8 *pos; 321 u8 *pos;
@@ -337,8 +337,8 @@ int mesh_add_awake_window_ie(struct sk_buff *skb,
337 return 0; 337 return 0;
338} 338}
339 339
340int 340int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata,
341mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 341 struct sk_buff *skb)
342{ 342{
343 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 343 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
344 u8 offset, len; 344 u8 offset, len;
@@ -361,8 +361,7 @@ mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
361 return 0; 361 return 0;
362} 362}
363 363
364int 364int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
365mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
366{ 365{
367 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 366 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
368 u8 len = 0; 367 u8 len = 0;
@@ -390,8 +389,8 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
390 return 0; 389 return 0;
391} 390}
392 391
393int mesh_add_ds_params_ie(struct sk_buff *skb, 392static int mesh_add_ds_params_ie(struct ieee80211_sub_if_data *sdata,
394 struct ieee80211_sub_if_data *sdata) 393 struct sk_buff *skb)
395{ 394{
396 struct ieee80211_chanctx_conf *chanctx_conf; 395 struct ieee80211_chanctx_conf *chanctx_conf;
397 struct ieee80211_channel *chan; 396 struct ieee80211_channel *chan;
@@ -417,8 +416,8 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
417 return 0; 416 return 0;
418} 417}
419 418
420int mesh_add_ht_cap_ie(struct sk_buff *skb, 419int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
421 struct ieee80211_sub_if_data *sdata) 420 struct sk_buff *skb)
422{ 421{
423 struct ieee80211_local *local = sdata->local; 422 struct ieee80211_local *local = sdata->local;
424 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 423 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
@@ -439,8 +438,8 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
439 return 0; 438 return 0;
440} 439}
441 440
442int mesh_add_ht_oper_ie(struct sk_buff *skb, 441int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
443 struct ieee80211_sub_if_data *sdata) 442 struct sk_buff *skb)
444{ 443{
445 struct ieee80211_local *local = sdata->local; 444 struct ieee80211_local *local = sdata->local;
446 struct ieee80211_chanctx_conf *chanctx_conf; 445 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -475,6 +474,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
475 474
476 return 0; 475 return 0;
477} 476}
477
478static void ieee80211_mesh_path_timer(unsigned long data) 478static void ieee80211_mesh_path_timer(unsigned long data)
479{ 479{
480 struct ieee80211_sub_if_data *sdata = 480 struct ieee80211_sub_if_data *sdata =
@@ -520,7 +520,7 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
520 520
521/** 521/**
522 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame 522 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
523 * @hdr: 802.11 frame header 523 * @hdr: 802.11 frame header
524 * @fc: frame control field 524 * @fc: frame control field
525 * @meshda: destination address in the mesh 525 * @meshda: destination address in the mesh
526 * @meshsa: source address address in the mesh. Same as TA, as frame is 526 * @meshsa: source address address in the mesh. Same as TA, as frame is
@@ -551,8 +551,8 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
551 551
552/** 552/**
553 * ieee80211_new_mesh_header - create a new mesh header 553 * ieee80211_new_mesh_header - create a new mesh header
554 * @meshhdr: uninitialized mesh header
555 * @sdata: mesh interface to be used 554 * @sdata: mesh interface to be used
555 * @meshhdr: uninitialized mesh header
556 * @addr4or5: 1st address in the ae header, which may correspond to address 4 556 * @addr4or5: 1st address in the ae header, which may correspond to address 4
557 * (if addr6 is NULL) or address 5 (if addr6 is present). It may 557 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
558 * be NULL. 558 * be NULL.
@@ -561,32 +561,38 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
561 * 561 *
562 * Return the header length. 562 * Return the header length.
563 */ 563 */
564int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 564int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
565 struct ieee80211_sub_if_data *sdata, char *addr4or5, 565 struct ieee80211s_hdr *meshhdr,
566 char *addr6) 566 const char *addr4or5, const char *addr6)
567{ 567{
568 int aelen = 0; 568 if (WARN_ON(!addr4or5 && addr6))
569 BUG_ON(!addr4or5 && addr6); 569 return 0;
570
570 memset(meshhdr, 0, sizeof(*meshhdr)); 571 memset(meshhdr, 0, sizeof(*meshhdr));
572
571 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 573 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
574
575 /* FIXME: racy -- TX on multiple queues can be concurrent */
572 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 576 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
573 sdata->u.mesh.mesh_seqnum++; 577 sdata->u.mesh.mesh_seqnum++;
578
574 if (addr4or5 && !addr6) { 579 if (addr4or5 && !addr6) {
575 meshhdr->flags |= MESH_FLAGS_AE_A4; 580 meshhdr->flags |= MESH_FLAGS_AE_A4;
576 aelen += ETH_ALEN;
577 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); 581 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
582 return 2 * ETH_ALEN;
578 } else if (addr4or5 && addr6) { 583 } else if (addr4or5 && addr6) {
579 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 584 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
580 aelen += 2 * ETH_ALEN;
581 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); 585 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
582 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); 586 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
587 return 3 * ETH_ALEN;
583 } 588 }
584 return 6 + aelen; 589
590 return ETH_ALEN;
585} 591}
586 592
587static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 593static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
588 struct ieee80211_if_mesh *ifmsh)
589{ 594{
595 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
590 u32 changed; 596 u32 changed;
591 597
592 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 598 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
@@ -596,7 +602,8 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
596 ieee80211_mbss_info_change_notify(sdata, changed); 602 ieee80211_mbss_info_change_notify(sdata, changed);
597 603
598 mod_timer(&ifmsh->housekeeping_timer, 604 mod_timer(&ifmsh->housekeeping_timer,
599 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 605 round_jiffies(jiffies +
606 IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
600} 607}
601 608
602static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) 609static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
@@ -708,7 +715,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
708 *pos++ = 0x0; 715 *pos++ = 0x0;
709 716
710 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 717 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
711 mesh_add_ds_params_ie(skb, sdata)) 718 mesh_add_ds_params_ie(sdata, skb))
712 goto out_free; 719 goto out_free;
713 720
714 bcn->head_len = skb->len; 721 bcn->head_len = skb->len;
@@ -719,13 +726,13 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
719 bcn->tail = bcn->head + bcn->head_len; 726 bcn->tail = bcn->head + bcn->head_len;
720 727
721 if (ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 728 if (ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
722 mesh_add_rsn_ie(skb, sdata) || 729 mesh_add_rsn_ie(sdata, skb) ||
723 mesh_add_ht_cap_ie(skb, sdata) || 730 mesh_add_ht_cap_ie(sdata, skb) ||
724 mesh_add_ht_oper_ie(skb, sdata) || 731 mesh_add_ht_oper_ie(sdata, skb) ||
725 mesh_add_meshid_ie(skb, sdata) || 732 mesh_add_meshid_ie(sdata, skb) ||
726 mesh_add_meshconf_ie(skb, sdata) || 733 mesh_add_meshconf_ie(sdata, skb) ||
727 mesh_add_awake_window_ie(skb, sdata) || 734 mesh_add_awake_window_ie(sdata, skb) ||
728 mesh_add_vendor_ies(skb, sdata)) 735 mesh_add_vendor_ies(sdata, skb))
729 goto out_free; 736 goto out_free;
730 737
731 bcn->tail_len = skb->len; 738 bcn->tail_len = skb->len;
@@ -1039,7 +1046,7 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
1039 mesh_mpp_table_grow(); 1046 mesh_mpp_table_grow();
1040 1047
1041 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) 1048 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
1042 ieee80211_mesh_housekeeping(sdata, ifmsh); 1049 ieee80211_mesh_housekeeping(sdata);
1043 1050
1044 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags)) 1051 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
1045 ieee80211_mesh_rootpath(sdata); 1052 ieee80211_mesh_rootpath(sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 1a1da877b1d2..336c88a16687 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -26,12 +26,12 @@
26 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding 26 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
27 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path 27 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
28 * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence 28 * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
29 * number 29 * number
30 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be 30 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be
31 * modified 31 * modified
32 * @MESH_PATH_RESOLVED: the mesh path can has been resolved 32 * @MESH_PATH_RESOLVED: the mesh path can has been resolved
33 * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination 33 * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
34 * already queued up, waiting for the discovery process to start. 34 * already queued up, waiting for the discovery process to start.
35 * 35 *
36 * MESH_PATH_RESOLVED is used by the mesh path timer to 36 * MESH_PATH_RESOLVED is used by the mesh path timer to
37 * decide when to stop or cancel the mesh path discovery. 37 * decide when to stop or cancel the mesh path discovery.
@@ -73,16 +73,16 @@ enum mesh_deferred_task_flags {
73 * @dst: mesh path destination mac address 73 * @dst: mesh path destination mac address
74 * @sdata: mesh subif 74 * @sdata: mesh subif
75 * @next_hop: mesh neighbor to which frames for this destination will be 75 * @next_hop: mesh neighbor to which frames for this destination will be
76 * forwarded 76 * forwarded
77 * @timer: mesh path discovery timer 77 * @timer: mesh path discovery timer
78 * @frame_queue: pending queue for frames sent to this destination while the 78 * @frame_queue: pending queue for frames sent to this destination while the
79 * path is unresolved 79 * path is unresolved
80 * @sn: target sequence number 80 * @sn: target sequence number
81 * @metric: current metric to this destination 81 * @metric: current metric to this destination
82 * @hop_count: hops to destination 82 * @hop_count: hops to destination
83 * @exp_time: in jiffies, when the path will expire or when it expired 83 * @exp_time: in jiffies, when the path will expire or when it expired
84 * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery 84 * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
85 * retry 85 * retry
86 * @discovery_retries: number of discovery retries 86 * @discovery_retries: number of discovery retries
87 * @flags: mesh path flags, as specified on &enum mesh_path_flags 87 * @flags: mesh path flags, as specified on &enum mesh_path_flags
88 * @state_lock: mesh path state lock used to protect changes to the 88 * @state_lock: mesh path state lock used to protect changes to the
@@ -206,38 +206,33 @@ struct mesh_rmc {
206/* Various */ 206/* Various */
207int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 207int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
208 const u8 *da, const u8 *sa); 208 const u8 *da, const u8 *sa);
209int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 209int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
210 struct ieee80211_sub_if_data *sdata, char *addr4or5, 210 struct ieee80211s_hdr *meshhdr,
211 char *addr6); 211 const char *addr4or5, const char *addr6);
212int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 212int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
213 struct ieee80211_sub_if_data *sdata); 213 const u8 *addr, struct ieee80211s_hdr *mesh_hdr);
214bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 214bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
215 struct ieee802_11_elems *ie); 215 struct ieee802_11_elems *ie);
216void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 216void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
217void mesh_mgmt_ies_add(struct sk_buff *skb, 217void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata,
218 struct ieee80211_sub_if_data *sdata); 218 struct sk_buff *skb);
219int mesh_add_meshconf_ie(struct sk_buff *skb, 219int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
220 struct ieee80211_sub_if_data *sdata); 220 struct sk_buff *skb);
221int mesh_add_meshid_ie(struct sk_buff *skb, 221int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata,
222 struct ieee80211_sub_if_data *sdata); 222 struct sk_buff *skb);
223int mesh_add_rsn_ie(struct sk_buff *skb, 223int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata,
224 struct ieee80211_sub_if_data *sdata); 224 struct sk_buff *skb);
225int mesh_add_awake_window_ie(struct sk_buff *skb, 225int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata,
226 struct ieee80211_sub_if_data *sdata); 226 struct sk_buff *skb);
227int mesh_add_vendor_ies(struct sk_buff *skb, 227int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
228 struct ieee80211_sub_if_data *sdata); 228 struct sk_buff *skb);
229int mesh_add_ds_params_ie(struct sk_buff *skb, 229int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
230 struct ieee80211_sub_if_data *sdata); 230 struct sk_buff *skb);
231int mesh_add_ht_cap_ie(struct sk_buff *skb,
232 struct ieee80211_sub_if_data *sdata);
233int mesh_add_ht_oper_ie(struct sk_buff *skb,
234 struct ieee80211_sub_if_data *sdata);
235void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 231void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
236int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 232int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
237void ieee80211s_init(void); 233void ieee80211s_init(void);
238void ieee80211s_update_metric(struct ieee80211_local *local, 234void ieee80211s_update_metric(struct ieee80211_local *local,
239 struct sta_info *sta, struct sk_buff *skb); 235 struct sta_info *sta, struct sk_buff *skb);
240void ieee80211s_stop(void);
241void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 236void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
242int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 237int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
243void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); 238void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
@@ -263,31 +258,32 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
263 struct ieee802_11_elems *elems); 258 struct ieee802_11_elems *elems);
264 259
265/* Mesh paths */ 260/* Mesh paths */
266int mesh_nexthop_lookup(struct sk_buff *skb, 261int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
267 struct ieee80211_sub_if_data *sdata); 262 struct sk_buff *skb);
268int mesh_nexthop_resolve(struct sk_buff *skb, 263int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
269 struct ieee80211_sub_if_data *sdata); 264 struct sk_buff *skb);
270void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata); 265void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
271struct mesh_path *mesh_path_lookup(const u8 *dst, 266struct mesh_path *mesh_path_lookup(struct ieee80211_sub_if_data *sdata,
272 struct ieee80211_sub_if_data *sdata); 267 const u8 *dst);
273struct mesh_path *mpp_path_lookup(u8 *dst, 268struct mesh_path *mpp_path_lookup(struct ieee80211_sub_if_data *sdata,
274 struct ieee80211_sub_if_data *sdata); 269 const u8 *dst);
275int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata); 270int mpp_path_add(struct ieee80211_sub_if_data *sdata,
276struct mesh_path *mesh_path_lookup_by_idx(int idx, 271 const u8 *dst, const u8 *mpp);
277 struct ieee80211_sub_if_data *sdata); 272struct mesh_path *
273mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
278void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 274void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
279void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 275void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
280void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 276void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
281 struct ieee80211_mgmt *mgmt, size_t len); 277 struct ieee80211_mgmt *mgmt, size_t len);
282int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata); 278int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst);
283 279
284int mesh_path_add_gate(struct mesh_path *mpath); 280int mesh_path_add_gate(struct mesh_path *mpath);
285int mesh_path_send_to_gates(struct mesh_path *mpath); 281int mesh_path_send_to_gates(struct mesh_path *mpath);
286int mesh_gate_num(struct ieee80211_sub_if_data *sdata); 282int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
283
287/* Mesh plinks */ 284/* Mesh plinks */
288void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 285void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
289 u8 *hw_addr, 286 u8 *hw_addr, struct ieee802_11_elems *ie);
290 struct ieee802_11_elems *ie);
291bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 287bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
292u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 288u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
293void mesh_plink_broken(struct sta_info *sta); 289void mesh_plink_broken(struct sta_info *sta);
@@ -304,19 +300,19 @@ void mesh_sta_cleanup(struct sta_info *sta);
304void mesh_mpath_table_grow(void); 300void mesh_mpath_table_grow(void);
305void mesh_mpp_table_grow(void); 301void mesh_mpp_table_grow(void);
306/* Mesh paths */ 302/* Mesh paths */
307int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, 303int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
308 __le16 target_rcode, const u8 *ra, 304 u8 ttl, const u8 *target, __le32 target_sn,
309 struct ieee80211_sub_if_data *sdata); 305 __le16 target_rcode, const u8 *ra);
310void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 306void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
311void mesh_path_flush_pending(struct mesh_path *mpath); 307void mesh_path_flush_pending(struct mesh_path *mpath);
312void mesh_path_tx_pending(struct mesh_path *mpath); 308void mesh_path_tx_pending(struct mesh_path *mpath);
313int mesh_pathtbl_init(void); 309int mesh_pathtbl_init(void);
314void mesh_pathtbl_unregister(void); 310void mesh_pathtbl_unregister(void);
315int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata); 311int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
316void mesh_path_timer(unsigned long data); 312void mesh_path_timer(unsigned long data);
317void mesh_path_flush_by_nexthop(struct sta_info *sta); 313void mesh_path_flush_by_nexthop(struct sta_info *sta);
318void mesh_path_discard_frame(struct sk_buff *skb, 314void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
319 struct ieee80211_sub_if_data *sdata); 315 struct sk_buff *skb);
320void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); 316void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
321void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 317void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
322void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 318void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
@@ -325,8 +321,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
325extern int mesh_paths_generation; 321extern int mesh_paths_generation;
326 322
327#ifdef CONFIG_MAC80211_MESH 323#ifdef CONFIG_MAC80211_MESH
328extern int mesh_allocated;
329
330static inline 324static inline
331u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 325u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
332{ 326{
@@ -371,8 +365,8 @@ void mesh_plink_quiesce(struct sta_info *sta);
371void mesh_plink_restart(struct sta_info *sta); 365void mesh_plink_restart(struct sta_info *sta);
372void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 366void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
373void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 367void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
368void ieee80211s_stop(void);
374#else 369#else
375#define mesh_allocated 0
376static inline void 370static inline void
377ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} 371ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
378static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) 372static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
@@ -385,6 +379,7 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
385{ return false; } 379{ return false; }
386static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) 380static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
387{} 381{}
382static inline void ieee80211s_stop(void) {}
388#endif 383#endif
389 384
390#endif /* IEEE80211S_H */ 385#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 585c1e26cca8..bdb8d3b14587 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -238,9 +238,9 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
238 * also acquires in the TX path. To avoid a deadlock we don't transmit the 238 * also acquires in the TX path. To avoid a deadlock we don't transmit the
239 * frame directly but add it to the pending queue instead. 239 * frame directly but add it to the pending queue instead.
240 */ 240 */
241int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, 241int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
242 __le16 target_rcode, const u8 *ra, 242 u8 ttl, const u8 *target, __le32 target_sn,
243 struct ieee80211_sub_if_data *sdata) 243 __le16 target_rcode, const u8 *ra)
244{ 244{
245 struct ieee80211_local *local = sdata->local; 245 struct ieee80211_local *local = sdata->local;
246 struct sk_buff *skb; 246 struct sk_buff *skb;
@@ -430,7 +430,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
430 process = false; 430 process = false;
431 fresh_info = false; 431 fresh_info = false;
432 } else { 432 } else {
433 mpath = mesh_path_lookup(orig_addr, sdata); 433 mpath = mesh_path_lookup(sdata, orig_addr);
434 if (mpath) { 434 if (mpath) {
435 spin_lock_bh(&mpath->state_lock); 435 spin_lock_bh(&mpath->state_lock);
436 if (mpath->flags & MESH_PATH_FIXED) 436 if (mpath->flags & MESH_PATH_FIXED)
@@ -445,8 +445,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
445 } 445 }
446 } 446 }
447 } else { 447 } else {
448 mesh_path_add(orig_addr, sdata); 448 mesh_path_add(sdata, orig_addr);
449 mpath = mesh_path_lookup(orig_addr, sdata); 449 mpath = mesh_path_lookup(sdata, orig_addr);
450 if (!mpath) { 450 if (!mpath) {
451 rcu_read_unlock(); 451 rcu_read_unlock();
452 return 0; 452 return 0;
@@ -478,7 +478,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
478 else { 478 else {
479 fresh_info = true; 479 fresh_info = true;
480 480
481 mpath = mesh_path_lookup(ta, sdata); 481 mpath = mesh_path_lookup(sdata, ta);
482 if (mpath) { 482 if (mpath) {
483 spin_lock_bh(&mpath->state_lock); 483 spin_lock_bh(&mpath->state_lock);
484 if ((mpath->flags & MESH_PATH_FIXED) || 484 if ((mpath->flags & MESH_PATH_FIXED) ||
@@ -486,8 +486,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
486 (last_hop_metric > mpath->metric))) 486 (last_hop_metric > mpath->metric)))
487 fresh_info = false; 487 fresh_info = false;
488 } else { 488 } else {
489 mesh_path_add(ta, sdata); 489 mesh_path_add(sdata, ta);
490 mpath = mesh_path_lookup(ta, sdata); 490 mpath = mesh_path_lookup(sdata, ta);
491 if (!mpath) { 491 if (!mpath) {
492 rcu_read_unlock(); 492 rcu_read_unlock();
493 return 0; 493 return 0;
@@ -553,7 +553,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
553 } else if (is_broadcast_ether_addr(target_addr) && 553 } else if (is_broadcast_ether_addr(target_addr) &&
554 (target_flags & IEEE80211_PREQ_TO_FLAG)) { 554 (target_flags & IEEE80211_PREQ_TO_FLAG)) {
555 rcu_read_lock(); 555 rcu_read_lock();
556 mpath = mesh_path_lookup(orig_addr, sdata); 556 mpath = mesh_path_lookup(sdata, orig_addr);
557 if (mpath) { 557 if (mpath) {
558 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { 558 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
559 reply = true; 559 reply = true;
@@ -568,7 +568,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
568 rcu_read_unlock(); 568 rcu_read_unlock();
569 } else { 569 } else {
570 rcu_read_lock(); 570 rcu_read_lock();
571 mpath = mesh_path_lookup(target_addr, sdata); 571 mpath = mesh_path_lookup(sdata, target_addr);
572 if (mpath) { 572 if (mpath) {
573 if ((!(mpath->flags & MESH_PATH_SN_VALID)) || 573 if ((!(mpath->flags & MESH_PATH_SN_VALID)) ||
574 SN_LT(mpath->sn, target_sn)) { 574 SN_LT(mpath->sn, target_sn)) {
@@ -678,7 +678,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
678 } 678 }
679 679
680 rcu_read_lock(); 680 rcu_read_lock();
681 mpath = mesh_path_lookup(orig_addr, sdata); 681 mpath = mesh_path_lookup(sdata, orig_addr);
682 if (mpath) 682 if (mpath)
683 spin_lock_bh(&mpath->state_lock); 683 spin_lock_bh(&mpath->state_lock);
684 else 684 else
@@ -736,7 +736,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
736 target_rcode = PERR_IE_TARGET_RCODE(perr_elem); 736 target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
737 737
738 rcu_read_lock(); 738 rcu_read_lock();
739 mpath = mesh_path_lookup(target_addr, sdata); 739 mpath = mesh_path_lookup(sdata, target_addr);
740 if (mpath) { 740 if (mpath) {
741 struct sta_info *sta; 741 struct sta_info *sta;
742 742
@@ -751,9 +751,10 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
751 spin_unlock_bh(&mpath->state_lock); 751 spin_unlock_bh(&mpath->state_lock);
752 if (!ifmsh->mshcfg.dot11MeshForwarding) 752 if (!ifmsh->mshcfg.dot11MeshForwarding)
753 goto endperr; 753 goto endperr;
754 mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), 754 mesh_path_error_tx(sdata, ttl, target_addr,
755 cpu_to_le32(target_sn),
755 cpu_to_le16(target_rcode), 756 cpu_to_le16(target_rcode),
756 broadcast_addr, sdata); 757 broadcast_addr);
757 } else 758 } else
758 spin_unlock_bh(&mpath->state_lock); 759 spin_unlock_bh(&mpath->state_lock);
759 } 760 }
@@ -801,10 +802,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
801 802
802 metric_txsta = airtime_link_metric_get(local, sta); 803 metric_txsta = airtime_link_metric_get(local, sta);
803 804
804 mpath = mesh_path_lookup(orig_addr, sdata); 805 mpath = mesh_path_lookup(sdata, orig_addr);
805 if (!mpath) { 806 if (!mpath) {
806 mesh_path_add(orig_addr, sdata); 807 mesh_path_add(sdata, orig_addr);
807 mpath = mesh_path_lookup(orig_addr, sdata); 808 mpath = mesh_path_lookup(sdata, orig_addr);
808 if (!mpath) { 809 if (!mpath) {
809 rcu_read_unlock(); 810 rcu_read_unlock();
810 sdata->u.mesh.mshstats.dropped_frames_no_route++; 811 sdata->u.mesh.mshstats.dropped_frames_no_route++;
@@ -861,8 +862,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
861 862
862 863
863void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 864void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
864 struct ieee80211_mgmt *mgmt, 865 struct ieee80211_mgmt *mgmt, size_t len)
865 size_t len)
866{ 866{
867 struct ieee802_11_elems elems; 867 struct ieee802_11_elems elems;
868 size_t baselen; 868 size_t baselen;
@@ -1006,7 +1006,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
1006 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); 1006 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
1007 1007
1008 rcu_read_lock(); 1008 rcu_read_lock();
1009 mpath = mesh_path_lookup(preq_node->dst, sdata); 1009 mpath = mesh_path_lookup(sdata, preq_node->dst);
1010 if (!mpath) 1010 if (!mpath)
1011 goto enddiscovery; 1011 goto enddiscovery;
1012 1012
@@ -1076,8 +1076,8 @@ enddiscovery:
1076 * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. 1076 * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
1077 * skb is freeed here if no mpath could be allocated. 1077 * skb is freeed here if no mpath could be allocated.
1078 */ 1078 */
1079int mesh_nexthop_resolve(struct sk_buff *skb, 1079int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
1080 struct ieee80211_sub_if_data *sdata) 1080 struct sk_buff *skb)
1081{ 1081{
1082 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1082 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1083 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1083 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1091,17 +1091,17 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
1091 return 0; 1091 return 0;
1092 1092
1093 rcu_read_lock(); 1093 rcu_read_lock();
1094 err = mesh_nexthop_lookup(skb, sdata); 1094 err = mesh_nexthop_lookup(sdata, skb);
1095 if (!err) 1095 if (!err)
1096 goto endlookup; 1096 goto endlookup;
1097 1097
1098 /* no nexthop found, start resolving */ 1098 /* no nexthop found, start resolving */
1099 mpath = mesh_path_lookup(target_addr, sdata); 1099 mpath = mesh_path_lookup(sdata, target_addr);
1100 if (!mpath) { 1100 if (!mpath) {
1101 mesh_path_add(target_addr, sdata); 1101 mesh_path_add(sdata, target_addr);
1102 mpath = mesh_path_lookup(target_addr, sdata); 1102 mpath = mesh_path_lookup(sdata, target_addr);
1103 if (!mpath) { 1103 if (!mpath) {
1104 mesh_path_discard_frame(skb, sdata); 1104 mesh_path_discard_frame(sdata, skb);
1105 err = -ENOSPC; 1105 err = -ENOSPC;
1106 goto endlookup; 1106 goto endlookup;
1107 } 1107 }
@@ -1118,12 +1118,13 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
1118 skb_queue_tail(&mpath->frame_queue, skb); 1118 skb_queue_tail(&mpath->frame_queue, skb);
1119 err = -ENOENT; 1119 err = -ENOENT;
1120 if (skb_to_free) 1120 if (skb_to_free)
1121 mesh_path_discard_frame(skb_to_free, sdata); 1121 mesh_path_discard_frame(sdata, skb_to_free);
1122 1122
1123endlookup: 1123endlookup:
1124 rcu_read_unlock(); 1124 rcu_read_unlock();
1125 return err; 1125 return err;
1126} 1126}
1127
1127/** 1128/**
1128 * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling 1129 * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
1129 * this function is considered "using" the associated mpath, so preempt a path 1130 * this function is considered "using" the associated mpath, so preempt a path
@@ -1134,8 +1135,8 @@ endlookup:
1134 * 1135 *
1135 * Returns: 0 if the next hop was found. Nonzero otherwise. 1136 * Returns: 0 if the next hop was found. Nonzero otherwise.
1136 */ 1137 */
1137int mesh_nexthop_lookup(struct sk_buff *skb, 1138int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
1138 struct ieee80211_sub_if_data *sdata) 1139 struct sk_buff *skb)
1139{ 1140{
1140 struct mesh_path *mpath; 1141 struct mesh_path *mpath;
1141 struct sta_info *next_hop; 1142 struct sta_info *next_hop;
@@ -1144,7 +1145,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
1144 int err = -ENOENT; 1145 int err = -ENOENT;
1145 1146
1146 rcu_read_lock(); 1147 rcu_read_lock();
1147 mpath = mesh_path_lookup(target_addr, sdata); 1148 mpath = mesh_path_lookup(sdata, target_addr);
1148 1149
1149 if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) 1150 if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
1150 goto endlookup; 1151 goto endlookup;
@@ -1203,8 +1204,7 @@ void mesh_path_timer(unsigned long data)
1203 } 1204 }
1204} 1205}
1205 1206
1206void 1207void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1207mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1208{ 1208{
1209 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1209 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1210 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; 1210 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 2ce4c4023a97..6b3c4e119c63 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -24,9 +24,12 @@
24/* Keep the mean chain length below this constant */ 24/* Keep the mean chain length below this constant */
25#define MEAN_CHAIN_LEN 2 25#define MEAN_CHAIN_LEN 2
26 26
27#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \ 27static inline bool mpath_expired(struct mesh_path *mpath)
28 time_after(jiffies, mpath->exp_time) && \ 28{
29 !(mpath->flags & MESH_PATH_FIXED)) 29 return (mpath->flags & MESH_PATH_ACTIVE) &&
30 time_after(jiffies, mpath->exp_time) &&
31 !(mpath->flags & MESH_PATH_FIXED);
32}
30 33
31struct mpath_node { 34struct mpath_node {
32 struct hlist_node list; 35 struct hlist_node list;
@@ -185,8 +188,8 @@ static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata,
185 struct mesh_table *tbl) 188 struct mesh_table *tbl)
186{ 189{
187 /* Use last four bytes of hw addr and interface index as hash index */ 190 /* Use last four bytes of hw addr and interface index as hash index */
188 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) 191 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex,
189 & tbl->hash_mask; 192 tbl->hash_rnd) & tbl->hash_mask;
190} 193}
191 194
192 195
@@ -339,7 +342,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
339 mpath = node->mpath; 342 mpath = node->mpath;
340 if (mpath->sdata == sdata && 343 if (mpath->sdata == sdata &&
341 ether_addr_equal(dst, mpath->dst)) { 344 ether_addr_equal(dst, mpath->dst)) {
342 if (MPATH_EXPIRED(mpath)) { 345 if (mpath_expired(mpath)) {
343 spin_lock_bh(&mpath->state_lock); 346 spin_lock_bh(&mpath->state_lock);
344 mpath->flags &= ~MESH_PATH_ACTIVE; 347 mpath->flags &= ~MESH_PATH_ACTIVE;
345 spin_unlock_bh(&mpath->state_lock); 348 spin_unlock_bh(&mpath->state_lock);
@@ -352,20 +355,21 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
352 355
353/** 356/**
354 * mesh_path_lookup - look up a path in the mesh path table 357 * mesh_path_lookup - look up a path in the mesh path table
355 * @dst: hardware address (ETH_ALEN length) of destination
356 * @sdata: local subif 358 * @sdata: local subif
359 * @dst: hardware address (ETH_ALEN length) of destination
357 * 360 *
358 * Returns: pointer to the mesh path structure, or NULL if not found 361 * Returns: pointer to the mesh path structure, or NULL if not found
359 * 362 *
360 * Locking: must be called within a read rcu section. 363 * Locking: must be called within a read rcu section.
361 */ 364 */
362struct mesh_path *mesh_path_lookup(const u8 *dst, 365struct mesh_path *
363 struct ieee80211_sub_if_data *sdata) 366mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
364{ 367{
365 return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata); 368 return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata);
366} 369}
367 370
368struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) 371struct mesh_path *
372mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
369{ 373{
370 return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata); 374 return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata);
371} 375}
@@ -380,7 +384,8 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
380 * 384 *
381 * Locking: must be called within a read rcu section. 385 * Locking: must be called within a read rcu section.
382 */ 386 */
383struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) 387struct mesh_path *
388mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
384{ 389{
385 struct mesh_table *tbl = rcu_dereference(mesh_paths); 390 struct mesh_table *tbl = rcu_dereference(mesh_paths);
386 struct mpath_node *node; 391 struct mpath_node *node;
@@ -392,7 +397,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
392 if (sdata && node->mpath->sdata != sdata) 397 if (sdata && node->mpath->sdata != sdata)
393 continue; 398 continue;
394 if (j++ == idx) { 399 if (j++ == idx) {
395 if (MPATH_EXPIRED(node->mpath)) { 400 if (mpath_expired(node->mpath)) {
396 spin_lock_bh(&node->mpath->state_lock); 401 spin_lock_bh(&node->mpath->state_lock);
397 node->mpath->flags &= ~MESH_PATH_ACTIVE; 402 node->mpath->flags &= ~MESH_PATH_ACTIVE;
398 spin_unlock_bh(&node->mpath->state_lock); 403 spin_unlock_bh(&node->mpath->state_lock);
@@ -436,11 +441,10 @@ int mesh_path_add_gate(struct mesh_path *mpath)
436 spin_lock_bh(&tbl->gates_lock); 441 spin_lock_bh(&tbl->gates_lock);
437 hlist_add_head_rcu(&new_gate->list, tbl->known_gates); 442 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
438 spin_unlock_bh(&tbl->gates_lock); 443 spin_unlock_bh(&tbl->gates_lock);
439 rcu_read_unlock();
440 mpath_dbg(mpath->sdata, 444 mpath_dbg(mpath->sdata,
441 "Mesh path: Recorded new gate: %pM. %d known gates\n", 445 "Mesh path: Recorded new gate: %pM. %d known gates\n",
442 mpath->dst, mpath->sdata->u.mesh.num_gates); 446 mpath->dst, mpath->sdata->u.mesh.num_gates);
443 return 0; 447 err = 0;
444err_rcu: 448err_rcu:
445 rcu_read_unlock(); 449 rcu_read_unlock();
446 return err; 450 return err;
@@ -451,30 +455,27 @@ err_rcu:
451 * @tbl: table which holds our list of known gates 455 * @tbl: table which holds our list of known gates
452 * @mpath: gate mpath 456 * @mpath: gate mpath
453 * 457 *
454 * Returns: 0 on success
455 *
456 * Locking: must be called inside rcu_read_lock() section 458 * Locking: must be called inside rcu_read_lock() section
457 */ 459 */
458static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) 460static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
459{ 461{
460 struct mpath_node *gate; 462 struct mpath_node *gate;
461 struct hlist_node *p, *q; 463 struct hlist_node *p, *q;
462 464
463 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) 465 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) {
464 if (gate->mpath == mpath) { 466 if (gate->mpath != mpath)
465 spin_lock_bh(&tbl->gates_lock); 467 continue;
466 hlist_del_rcu(&gate->list); 468 spin_lock_bh(&tbl->gates_lock);
467 kfree_rcu(gate, rcu); 469 hlist_del_rcu(&gate->list);
468 spin_unlock_bh(&tbl->gates_lock); 470 kfree_rcu(gate, rcu);
469 mpath->sdata->u.mesh.num_gates--; 471 spin_unlock_bh(&tbl->gates_lock);
470 mpath->is_gate = false; 472 mpath->sdata->u.mesh.num_gates--;
471 mpath_dbg(mpath->sdata, 473 mpath->is_gate = false;
472 "Mesh path: Deleted gate: %pM. %d known gates\n", 474 mpath_dbg(mpath->sdata,
473 mpath->dst, mpath->sdata->u.mesh.num_gates); 475 "Mesh path: Deleted gate: %pM. %d known gates\n",
474 break; 476 mpath->dst, mpath->sdata->u.mesh.num_gates);
475 } 477 break;
476 478 }
477 return 0;
478} 479}
479 480
480/** 481/**
@@ -488,14 +489,14 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
488 489
489/** 490/**
490 * mesh_path_add - allocate and add a new path to the mesh path table 491 * mesh_path_add - allocate and add a new path to the mesh path table
491 * @addr: destination address of the path (ETH_ALEN length) 492 * @dst: destination address of the path (ETH_ALEN length)
492 * @sdata: local subif 493 * @sdata: local subif
493 * 494 *
494 * Returns: 0 on success 495 * Returns: 0 on success
495 * 496 *
496 * State: the initial state of the new path is set to 0 497 * State: the initial state of the new path is set to 0
497 */ 498 */
498int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata) 499int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
499{ 500{
500 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 501 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
501 struct ieee80211_local *local = sdata->local; 502 struct ieee80211_local *local = sdata->local;
@@ -630,7 +631,8 @@ void mesh_mpp_table_grow(void)
630 write_unlock_bh(&pathtbl_resize_lock); 631 write_unlock_bh(&pathtbl_resize_lock);
631} 632}
632 633
633int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) 634int mpp_path_add(struct ieee80211_sub_if_data *sdata,
635 const u8 *dst, const u8 *mpp)
634{ 636{
635 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 637 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
636 struct ieee80211_local *local = sdata->local; 638 struct ieee80211_local *local = sdata->local;
@@ -739,9 +741,10 @@ void mesh_plink_broken(struct sta_info *sta)
739 mpath->flags &= ~MESH_PATH_ACTIVE; 741 mpath->flags &= ~MESH_PATH_ACTIVE;
740 ++mpath->sn; 742 ++mpath->sn;
741 spin_unlock_bh(&mpath->state_lock); 743 spin_unlock_bh(&mpath->state_lock);
742 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 744 mesh_path_error_tx(sdata,
743 mpath->dst, cpu_to_le32(mpath->sn), 745 sdata->u.mesh.mshcfg.element_ttl,
744 reason, bcast, sdata); 746 mpath->dst, cpu_to_le32(mpath->sn),
747 reason, bcast);
745 } 748 }
746 } 749 }
747 rcu_read_unlock(); 750 rcu_read_unlock();
@@ -856,7 +859,7 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
856 * 859 *
857 * Returns: 0 if successful 860 * Returns: 0 if successful
858 */ 861 */
859int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) 862int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
860{ 863{
861 struct mesh_table *tbl; 864 struct mesh_table *tbl;
862 struct mesh_path *mpath; 865 struct mesh_path *mpath;
@@ -965,8 +968,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
965 * 968 *
966 * Locking: the function must me called within a rcu_read_lock region 969 * Locking: the function must me called within a rcu_read_lock region
967 */ 970 */
968void mesh_path_discard_frame(struct sk_buff *skb, 971void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
969 struct ieee80211_sub_if_data *sdata) 972 struct sk_buff *skb)
970{ 973{
971 kfree_skb(skb); 974 kfree_skb(skb);
972 sdata->u.mesh.mshstats.dropped_frames_no_route++; 975 sdata->u.mesh.mshstats.dropped_frames_no_route++;
@@ -984,7 +987,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
984 struct sk_buff *skb; 987 struct sk_buff *skb;
985 988
986 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) 989 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
987 mesh_path_discard_frame(skb, mpath->sdata); 990 mesh_path_discard_frame(mpath->sdata, skb);
988} 991}
989 992
990/** 993/**
@@ -1105,7 +1108,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
1105 if ((!(mpath->flags & MESH_PATH_RESOLVING)) && 1108 if ((!(mpath->flags & MESH_PATH_RESOLVING)) &&
1106 (!(mpath->flags & MESH_PATH_FIXED)) && 1109 (!(mpath->flags & MESH_PATH_FIXED)) &&
1107 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) 1110 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
1108 mesh_path_del(mpath->dst, mpath->sdata); 1111 mesh_path_del(mpath->sdata, mpath->dst);
1109 } 1112 }
1110 rcu_read_unlock(); 1113 rcu_read_unlock();
1111} 1114}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f7526e509aa8..0b58e8139937 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -38,8 +38,8 @@ enum plink_event {
38}; 38};
39 39
40static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 40static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
41 enum ieee80211_self_protected_actioncode action, 41 enum ieee80211_self_protected_actioncode action,
42 u8 *da, __le16 llid, __le16 plid, __le16 reason); 42 u8 *da, __le16 llid, __le16 plid, __le16 reason);
43 43
44/** 44/**
45 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 45 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
@@ -231,8 +231,9 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
231} 231}
232 232
233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
234 enum ieee80211_self_protected_actioncode action, 234 enum ieee80211_self_protected_actioncode action,
235 u8 *da, __le16 llid, __le16 plid, __le16 reason) { 235 u8 *da, __le16 llid, __le16 plid, __le16 reason)
236{
236 struct ieee80211_local *local = sdata->local; 237 struct ieee80211_local *local = sdata->local;
237 struct sk_buff *skb; 238 struct sk_buff *skb;
238 struct ieee80211_tx_info *info; 239 struct ieee80211_tx_info *info;
@@ -283,13 +284,13 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
283 } 284 }
284 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 285 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
285 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 286 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
286 mesh_add_rsn_ie(skb, sdata) || 287 mesh_add_rsn_ie(sdata, skb) ||
287 mesh_add_meshid_ie(skb, sdata) || 288 mesh_add_meshid_ie(sdata, skb) ||
288 mesh_add_meshconf_ie(skb, sdata)) 289 mesh_add_meshconf_ie(sdata, skb))
289 goto free; 290 goto free;
290 } else { /* WLAN_SP_MESH_PEERING_CLOSE */ 291 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
291 info->flags |= IEEE80211_TX_CTL_NO_ACK; 292 info->flags |= IEEE80211_TX_CTL_NO_ACK;
292 if (mesh_add_meshid_ie(skb, sdata)) 293 if (mesh_add_meshid_ie(sdata, skb))
293 goto free; 294 goto free;
294 } 295 }
295 296
@@ -333,12 +334,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
333 } 334 }
334 335
335 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 336 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
336 if (mesh_add_ht_cap_ie(skb, sdata) || 337 if (mesh_add_ht_cap_ie(sdata, skb) ||
337 mesh_add_ht_oper_ie(skb, sdata)) 338 mesh_add_ht_oper_ie(sdata, skb))
338 goto free; 339 goto free;
339 } 340 }
340 341
341 if (mesh_add_vendor_ies(skb, sdata)) 342 if (mesh_add_vendor_ies(sdata, skb))
342 goto free; 343 goto free;
343 344
344 ieee80211_tx_skb(sdata, skb); 345 ieee80211_tx_skb(sdata, skb);
@@ -666,8 +667,9 @@ u32 mesh_plink_block(struct sta_info *sta)
666} 667}
667 668
668 669
669void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 670void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
670 size_t len, struct ieee80211_rx_status *rx_status) 671 struct ieee80211_mgmt *mgmt, size_t len,
672 struct ieee80211_rx_status *rx_status)
671{ 673{
672 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 674 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
673 struct ieee802_11_elems elems; 675 struct ieee802_11_elems elems;
@@ -680,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
680 u8 *baseaddr; 682 u8 *baseaddr;
681 u32 changed = 0; 683 u32 changed = 0;
682 __le16 plid, llid, reason; 684 __le16 plid, llid, reason;
683 static const char *mplstates[] = { 685 static const char * const mplstates[] = {
684 [NL80211_PLINK_LISTEN] = "LISTEN", 686 [NL80211_PLINK_LISTEN] = "LISTEN",
685 [NL80211_PLINK_OPN_SNT] = "OPN-SNT", 687 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
686 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", 688 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
@@ -708,13 +710,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
708 baselen += 4; 710 baselen += 4;
709 } 711 }
710 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 712 ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
713
711 if (!elems.peering) { 714 if (!elems.peering) {
712 mpl_dbg(sdata, 715 mpl_dbg(sdata,
713 "Mesh plink: missing necessary peer link ie\n"); 716 "Mesh plink: missing necessary peer link ie\n");
714 return; 717 return;
715 } 718 }
719
716 if (elems.rsn_len && 720 if (elems.rsn_len &&
717 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 721 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
718 mpl_dbg(sdata, 722 mpl_dbg(sdata,
719 "Mesh plink: can't establish link with secure peer\n"); 723 "Mesh plink: can't establish link with secure peer\n");
720 return; 724 return;
@@ -733,7 +737,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
733 } 737 }
734 738
735 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 739 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
736 (!elems.mesh_id || !elems.mesh_config)) { 740 (!elems.mesh_id || !elems.mesh_config)) {
737 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 741 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
738 return; 742 return;
739 } 743 }
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index aa8d1e437385..05a256b38e24 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -43,7 +43,7 @@ struct sync_method {
43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) 43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
44{ 44{
45 return (ie->mesh_config->meshconf_cap & 45 return (ie->mesh_config->meshconf_cap &
46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; 46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
47} 47}
48 48
49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) 49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
@@ -112,7 +112,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
112 112
113 if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { 113 if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) {
114 clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 114 clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
115 msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", sta->sta.addr); 115 msync_dbg(sdata, "STA %pM : is adjusting TBTT\n",
116 sta->sta.addr);
116 goto no_sync; 117 goto no_sync;
117 } 118 }
118 119
@@ -129,18 +130,15 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
129 sta->t_offset = t_t - t_r; 130 sta->t_offset = t_t - t_r;
130 131
131 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { 132 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
132 s64 t_clockdrift = sta->t_offset_setpoint 133 s64 t_clockdrift = sta->t_offset_setpoint - sta->t_offset;
133 - sta->t_offset;
134 msync_dbg(sdata, 134 msync_dbg(sdata,
135 "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n", 135 "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n",
136 sta->sta.addr, 136 sta->sta.addr, (long long) sta->t_offset,
137 (long long) sta->t_offset, 137 (long long) sta->t_offset_setpoint,
138 (long long)
139 sta->t_offset_setpoint,
140 (long long) t_clockdrift); 138 (long long) t_clockdrift);
141 139
142 if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || 140 if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT ||
143 t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { 141 t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) {
144 msync_dbg(sdata, 142 msync_dbg(sdata,
145 "STA %pM : t_clockdrift=%lld too large, setpoint reset\n", 143 "STA %pM : t_clockdrift=%lld too large, setpoint reset\n",
146 sta->sta.addr, 144 sta->sta.addr,
@@ -149,15 +147,10 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
149 goto no_sync; 147 goto no_sync;
150 } 148 }
151 149
152 rcu_read_unlock();
153
154 spin_lock_bh(&ifmsh->sync_offset_lock); 150 spin_lock_bh(&ifmsh->sync_offset_lock);
155 if (t_clockdrift > 151 if (t_clockdrift > ifmsh->sync_offset_clockdrift_max)
156 ifmsh->sync_offset_clockdrift_max) 152 ifmsh->sync_offset_clockdrift_max = t_clockdrift;
157 ifmsh->sync_offset_clockdrift_max
158 = t_clockdrift;
159 spin_unlock_bh(&ifmsh->sync_offset_lock); 153 spin_unlock_bh(&ifmsh->sync_offset_lock);
160
161 } else { 154 } else {
162 sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; 155 sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN;
163 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 156 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
@@ -165,9 +158,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
165 "STA %pM : offset was invalid, sta->t_offset=%lld\n", 158 "STA %pM : offset was invalid, sta->t_offset=%lld\n",
166 sta->sta.addr, 159 sta->sta.addr,
167 (long long) sta->t_offset); 160 (long long) sta->t_offset);
168 rcu_read_unlock();
169 } 161 }
170 return;
171 162
172no_sync: 163no_sync:
173 rcu_read_unlock(); 164 rcu_read_unlock();
@@ -177,14 +168,12 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
177{ 168{
178 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 169 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
179 170
180 WARN_ON(ifmsh->mesh_sp_id 171 WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
181 != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
182 BUG_ON(!rcu_read_lock_held()); 172 BUG_ON(!rcu_read_lock_held());
183 173
184 spin_lock_bh(&ifmsh->sync_offset_lock); 174 spin_lock_bh(&ifmsh->sync_offset_lock);
185 175
186 if (ifmsh->sync_offset_clockdrift_max > 176 if (ifmsh->sync_offset_clockdrift_max > TOFFSET_MINIMUM_ADJUSTMENT) {
187 TOFFSET_MINIMUM_ADJUSTMENT) {
188 /* Since ajusting the tsf here would 177 /* Since ajusting the tsf here would
189 * require a possibly blocking call 178 * require a possibly blocking call
190 * to the driver tsf setter, we punt 179 * to the driver tsf setter, we punt
@@ -193,8 +182,7 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
193 msync_dbg(sdata, 182 msync_dbg(sdata,
194 "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", 183 "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n",
195 ifmsh->sync_offset_clockdrift_max); 184 ifmsh->sync_offset_clockdrift_max);
196 set_bit(MESH_WORK_DRIFT_ADJUST, 185 set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags);
197 &ifmsh->wrkq_flags);
198 186
199 ifmsh->adjusting_tbtt = true; 187 ifmsh->adjusting_tbtt = true;
200 } else { 188 } else {
@@ -220,14 +208,11 @@ static const struct sync_method sync_methods[] = {
220 208
221const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) 209const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method)
222{ 210{
223 const struct ieee80211_mesh_sync_ops *ops = NULL; 211 int i;
224 u8 i;
225 212
226 for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) { 213 for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) {
227 if (sync_methods[i].method == method) { 214 if (sync_methods[i].method == method)
228 ops = &sync_methods[i].ops; 215 return &sync_methods[i].ops;
229 break;
230 }
231 } 216 }
232 return ops; 217 return NULL;
233} 218}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3acb70b73e22..bb73ed2d20b9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2027,7 +2027,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2027 /* frame is in RMC, don't forward */ 2027 /* frame is in RMC, don't forward */
2028 if (ieee80211_is_data(hdr->frame_control) && 2028 if (ieee80211_is_data(hdr->frame_control) &&
2029 is_multicast_ether_addr(hdr->addr1) && 2029 is_multicast_ether_addr(hdr->addr1) &&
2030 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) 2030 mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
2031 return RX_DROP_MONITOR; 2031 return RX_DROP_MONITOR;
2032 2032
2033 if (!ieee80211_is_data(hdr->frame_control) || 2033 if (!ieee80211_is_data(hdr->frame_control) ||
@@ -2054,9 +2054,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2054 } 2054 }
2055 2055
2056 rcu_read_lock(); 2056 rcu_read_lock();
2057 mppath = mpp_path_lookup(proxied_addr, sdata); 2057 mppath = mpp_path_lookup(sdata, proxied_addr);
2058 if (!mppath) { 2058 if (!mppath) {
2059 mpp_path_add(proxied_addr, mpp_addr, sdata); 2059 mpp_path_add(sdata, proxied_addr, mpp_addr);
2060 } else { 2060 } else {
2061 spin_lock_bh(&mppath->state_lock); 2061 spin_lock_bh(&mppath->state_lock);
2062 if (!ether_addr_equal(mppath->mpp, mpp_addr)) 2062 if (!ether_addr_equal(mppath->mpp, mpp_addr))
@@ -2104,13 +2104,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2104 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); 2104 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
2105 /* update power mode indication when forwarding */ 2105 /* update power mode indication when forwarding */
2106 ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); 2106 ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
2107 } else if (!mesh_nexthop_lookup(fwd_skb, sdata)) { 2107 } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
2108 /* mesh power mode flags updated in mesh_nexthop_lookup */ 2108 /* mesh power mode flags updated in mesh_nexthop_lookup */
2109 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); 2109 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
2110 } else { 2110 } else {
2111 /* unable to resolve next hop */ 2111 /* unable to resolve next hop */
2112 mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, 2112 mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
2113 0, reason, fwd_hdr->addr2, sdata); 2113 fwd_hdr->addr3, 0, reason, fwd_hdr->addr2);
2114 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); 2114 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
2115 kfree_skb(fwd_skb); 2115 kfree_skb(fwd_skb);
2116 return RX_DROP_MONITOR; 2116 return RX_DROP_MONITOR;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index fe644f91ae05..5b9602b62405 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1495,7 +1495,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1495 if (ieee80211_vif_is_mesh(&sdata->vif)) { 1495 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1496 if (ieee80211_is_data(hdr->frame_control) && 1496 if (ieee80211_is_data(hdr->frame_control) &&
1497 is_unicast_ether_addr(hdr->addr1)) { 1497 is_unicast_ether_addr(hdr->addr1)) {
1498 if (mesh_nexthop_resolve(skb, sdata)) 1498 if (mesh_nexthop_resolve(sdata, skb))
1499 return; /* skb queued: don't free */ 1499 return; /* skb queued: don't free */
1500 } else { 1500 } else {
1501 ieee80211_mps_set_frame_flags(sdata, NULL, hdr); 1501 ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
@@ -1844,9 +1844,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 } 1844 }
1845 1845
1846 if (!is_multicast_ether_addr(skb->data)) { 1846 if (!is_multicast_ether_addr(skb->data)) {
1847 mpath = mesh_path_lookup(skb->data, sdata); 1847 mpath = mesh_path_lookup(sdata, skb->data);
1848 if (!mpath) 1848 if (!mpath)
1849 mppath = mpp_path_lookup(skb->data, sdata); 1849 mppath = mpp_path_lookup(sdata, skb->data);
1850 } 1850 }
1851 1851
1852 /* 1852 /*
@@ -1859,8 +1859,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1859 !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { 1859 !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) {
1860 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1860 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1861 skb->data, skb->data + ETH_ALEN); 1861 skb->data, skb->data + ETH_ALEN);
1862 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1862 meshhdrlen = ieee80211_new_mesh_header(sdata, &mesh_hdr,
1863 sdata, NULL, NULL); 1863 NULL, NULL);
1864 } else { 1864 } else {
1865 /* DS -> MBSS (802.11-2012 13.11.3.3). 1865 /* DS -> MBSS (802.11-2012 13.11.3.3).
1866 * For unicast with unknown forwarding information, 1866 * For unicast with unknown forwarding information,
@@ -1879,18 +1879,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1879 mesh_da, sdata->vif.addr); 1879 mesh_da, sdata->vif.addr);
1880 if (is_multicast_ether_addr(mesh_da)) 1880 if (is_multicast_ether_addr(mesh_da))
1881 /* DA TA mSA AE:SA */ 1881 /* DA TA mSA AE:SA */
1882 meshhdrlen = 1882 meshhdrlen = ieee80211_new_mesh_header(
1883 ieee80211_new_mesh_header(&mesh_hdr, 1883 sdata, &mesh_hdr,
1884 sdata, 1884 skb->data + ETH_ALEN, NULL);
1885 skb->data + ETH_ALEN,
1886 NULL);
1887 else 1885 else
1888 /* RA TA mDA mSA AE:DA SA */ 1886 /* RA TA mDA mSA AE:DA SA */
1889 meshhdrlen = 1887 meshhdrlen = ieee80211_new_mesh_header(
1890 ieee80211_new_mesh_header(&mesh_hdr, 1888 sdata, &mesh_hdr, skb->data,
1891 sdata, 1889 skb->data + ETH_ALEN);
1892 skb->data,
1893 skb->data + ETH_ALEN);
1894 1890
1895 } 1891 }
1896 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1892 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);