aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);