diff options
Diffstat (limited to 'net/mac80211/mesh_pathtbl.c')
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 89 |
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) && \ | 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 | } |