aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_pathtbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh_pathtbl.c')
-rw-r--r--net/mac80211/mesh_pathtbl.c89
1 files changed, 46 insertions, 43 deletions
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}