diff options
-rw-r--r-- | net/mac80211/cfg.c | 14 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 115 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 105 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 68 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 89 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 36 | ||||
-rw-r--r-- | net/mac80211/mesh_sync.c | 47 | ||||
-rw-r--r-- | net/mac80211/rx.c | 12 | ||||
-rw-r--r-- | net/mac80211/tx.c | 26 |
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 | ||
1520 | static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, | 1520 | static 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 | ||
20 | int mesh_allocated; | 20 | static int mesh_allocated; |
21 | static struct kmem_cache *rm_cache; | 21 | static struct kmem_cache *rm_cache; |
22 | 22 | ||
23 | bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) | 23 | bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) |
@@ -36,6 +36,8 @@ void ieee80211s_init(void) | |||
36 | 36 | ||
37 | void ieee80211s_stop(void) | 37 | void 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; |
109 | mismatch: | ||
110 | return false; | ||
111 | } | 111 | } |
112 | 112 | ||
113 | /** | 113 | /** |
@@ -118,7 +118,7 @@ mismatch: | |||
118 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) | 118 | bool 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 | */ |
221 | int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, | 223 | int 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 | ||
256 | int | 257 | int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, |
257 | mesh_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 | ||
299 | int | 300 | int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
300 | mesh_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 | ||
317 | int mesh_add_awake_window_ie(struct sk_buff *skb, | 317 | static 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 | ||
340 | int | 340 | int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata, |
341 | mesh_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 | ||
364 | int | 364 | int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
365 | mesh_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 | ||
393 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 392 | static 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 | ||
420 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | 419 | int 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 | ||
442 | int mesh_add_ht_oper_ie(struct sk_buff *skb, | 441 | int 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 | |||
478 | static void ieee80211_mesh_path_timer(unsigned long data) | 478 | static 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 | */ |
564 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 564 | int 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 | ||
587 | static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | 593 | static 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 | ||
602 | static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) | 609 | static 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 */ |
207 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, | 207 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, |
208 | const u8 *da, const u8 *sa); | 208 | const u8 *da, const u8 *sa); |
209 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 209 | int 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); |
212 | int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, | 212 | int 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); |
214 | bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, | 214 | bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, |
215 | struct ieee802_11_elems *ie); | 215 | struct ieee802_11_elems *ie); |
216 | void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); | 216 | void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); |
217 | void mesh_mgmt_ies_add(struct sk_buff *skb, | 217 | void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata, |
218 | struct ieee80211_sub_if_data *sdata); | 218 | struct sk_buff *skb); |
219 | int mesh_add_meshconf_ie(struct sk_buff *skb, | 219 | int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, |
220 | struct ieee80211_sub_if_data *sdata); | 220 | struct sk_buff *skb); |
221 | int mesh_add_meshid_ie(struct sk_buff *skb, | 221 | int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, |
222 | struct ieee80211_sub_if_data *sdata); | 222 | struct sk_buff *skb); |
223 | int mesh_add_rsn_ie(struct sk_buff *skb, | 223 | int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata, |
224 | struct ieee80211_sub_if_data *sdata); | 224 | struct sk_buff *skb); |
225 | int mesh_add_awake_window_ie(struct sk_buff *skb, | 225 | int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata, |
226 | struct ieee80211_sub_if_data *sdata); | 226 | struct sk_buff *skb); |
227 | int mesh_add_vendor_ies(struct sk_buff *skb, | 227 | int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata, |
228 | struct ieee80211_sub_if_data *sdata); | 228 | struct sk_buff *skb); |
229 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 229 | int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata, |
230 | struct ieee80211_sub_if_data *sdata); | 230 | struct sk_buff *skb); |
231 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
232 | struct ieee80211_sub_if_data *sdata); | ||
233 | int mesh_add_ht_oper_ie(struct sk_buff *skb, | ||
234 | struct ieee80211_sub_if_data *sdata); | ||
235 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | 231 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); |
236 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 232 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
237 | void ieee80211s_init(void); | 233 | void ieee80211s_init(void); |
238 | void ieee80211s_update_metric(struct ieee80211_local *local, | 234 | void 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); |
240 | void ieee80211s_stop(void); | ||
241 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | 236 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); |
242 | int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); | 237 | int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); |
243 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); | 238 | void 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 */ |
266 | int mesh_nexthop_lookup(struct sk_buff *skb, | 261 | int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata, |
267 | struct ieee80211_sub_if_data *sdata); | 262 | struct sk_buff *skb); |
268 | int mesh_nexthop_resolve(struct sk_buff *skb, | 263 | int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata, |
269 | struct ieee80211_sub_if_data *sdata); | 264 | struct sk_buff *skb); |
270 | void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata); | 265 | void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata); |
271 | struct mesh_path *mesh_path_lookup(const u8 *dst, | 266 | struct mesh_path *mesh_path_lookup(struct ieee80211_sub_if_data *sdata, |
272 | struct ieee80211_sub_if_data *sdata); | 267 | const u8 *dst); |
273 | struct mesh_path *mpp_path_lookup(u8 *dst, | 268 | struct mesh_path *mpp_path_lookup(struct ieee80211_sub_if_data *sdata, |
274 | struct ieee80211_sub_if_data *sdata); | 269 | const u8 *dst); |
275 | int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata); | 270 | int mpp_path_add(struct ieee80211_sub_if_data *sdata, |
276 | struct mesh_path *mesh_path_lookup_by_idx(int idx, | 271 | const u8 *dst, const u8 *mpp); |
277 | struct ieee80211_sub_if_data *sdata); | 272 | struct mesh_path * |
273 | mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); | ||
278 | void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); | 274 | void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); |
279 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata); | 275 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata); |
280 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | 276 | void 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); |
282 | int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata); | 278 | int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); |
283 | 279 | ||
284 | int mesh_path_add_gate(struct mesh_path *mpath); | 280 | int mesh_path_add_gate(struct mesh_path *mpath); |
285 | int mesh_path_send_to_gates(struct mesh_path *mpath); | 281 | int mesh_path_send_to_gates(struct mesh_path *mpath); |
286 | int mesh_gate_num(struct ieee80211_sub_if_data *sdata); | 282 | int mesh_gate_num(struct ieee80211_sub_if_data *sdata); |
283 | |||
287 | /* Mesh plinks */ | 284 | /* Mesh plinks */ |
288 | void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, | 285 | void 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); | ||
291 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); | 287 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); |
292 | u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); | 288 | u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); |
293 | void mesh_plink_broken(struct sta_info *sta); | 289 | void mesh_plink_broken(struct sta_info *sta); |
@@ -304,19 +300,19 @@ void mesh_sta_cleanup(struct sta_info *sta); | |||
304 | void mesh_mpath_table_grow(void); | 300 | void mesh_mpath_table_grow(void); |
305 | void mesh_mpp_table_grow(void); | 301 | void mesh_mpp_table_grow(void); |
306 | /* Mesh paths */ | 302 | /* Mesh paths */ |
307 | int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, | 303 | int 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); |
310 | void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); | 306 | void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); |
311 | void mesh_path_flush_pending(struct mesh_path *mpath); | 307 | void mesh_path_flush_pending(struct mesh_path *mpath); |
312 | void mesh_path_tx_pending(struct mesh_path *mpath); | 308 | void mesh_path_tx_pending(struct mesh_path *mpath); |
313 | int mesh_pathtbl_init(void); | 309 | int mesh_pathtbl_init(void); |
314 | void mesh_pathtbl_unregister(void); | 310 | void mesh_pathtbl_unregister(void); |
315 | int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata); | 311 | int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); |
316 | void mesh_path_timer(unsigned long data); | 312 | void mesh_path_timer(unsigned long data); |
317 | void mesh_path_flush_by_nexthop(struct sta_info *sta); | 313 | void mesh_path_flush_by_nexthop(struct sta_info *sta); |
318 | void mesh_path_discard_frame(struct sk_buff *skb, | 314 | void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, |
319 | struct ieee80211_sub_if_data *sdata); | 315 | struct sk_buff *skb); |
320 | void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); | 316 | void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); |
321 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); | 317 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); |
322 | void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); | 318 | void 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); | |||
325 | extern int mesh_paths_generation; | 321 | extern int mesh_paths_generation; |
326 | 322 | ||
327 | #ifdef CONFIG_MAC80211_MESH | 323 | #ifdef CONFIG_MAC80211_MESH |
328 | extern int mesh_allocated; | ||
329 | |||
330 | static inline | 324 | static inline |
331 | u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) | 325 | u32 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); | |||
371 | void mesh_plink_restart(struct sta_info *sta); | 365 | void mesh_plink_restart(struct sta_info *sta); |
372 | void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); | 366 | void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); |
373 | void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); | 367 | void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); |
368 | void ieee80211s_stop(void); | ||
374 | #else | 369 | #else |
375 | #define mesh_allocated 0 | ||
376 | static inline void | 370 | static inline void |
377 | ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} | 371 | ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} |
378 | static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) | 372 | static 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; } |
386 | static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) | 380 | static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) |
387 | {} | 381 | {} |
382 | static 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 | */ |
241 | int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, | 241 | int 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 | ||
863 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | 864 | void 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 | */ |
1079 | int mesh_nexthop_resolve(struct sk_buff *skb, | 1079 | int 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 | ||
1123 | endlookup: | 1123 | endlookup: |
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 | */ |
1137 | int mesh_nexthop_lookup(struct sk_buff *skb, | 1138 | int 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 | ||
1206 | void | 1207 | void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) |
1207 | mesh_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) && \ | 27 | static 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 | ||
31 | struct mpath_node { | 34 | struct 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 | */ |
362 | struct mesh_path *mesh_path_lookup(const u8 *dst, | 365 | struct mesh_path * |
363 | struct ieee80211_sub_if_data *sdata) | 366 | mesh_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 | ||
368 | struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) | 371 | struct mesh_path * |
372 | mpp_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 | */ |
383 | struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) | 387 | struct mesh_path * |
388 | mesh_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; |
444 | err_rcu: | 448 | err_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 | */ |
458 | static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) | 460 | static 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 | */ |
498 | int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata) | 499 | int 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 | ||
633 | int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | 634 | int 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 | */ |
859 | int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | 862 | int 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 | */ |
968 | void mesh_path_discard_frame(struct sk_buff *skb, | 971 | void 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 | ||
40 | static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | 40 | static 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 | ||
233 | static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | 233 | static 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 | ||
669 | void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, | 670 | void 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 { | |||
43 | static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) | 43 | static 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 | ||
49 | void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | 49 | void 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 | ||
172 | no_sync: | 163 | no_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 | ||
221 | const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) | 209 | const 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); |