Lines Matching refs:mpath

19 static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
71 static inline bool mpath_expired(struct mesh_path *mpath) in mpath_expired() argument
73 return (mpath->flags & MESH_PATH_ACTIVE) && in mpath_expired()
74 time_after(jiffies, mpath->exp_time) && in mpath_expired()
75 !(mpath->flags & MESH_PATH_FIXED); in mpath_expired()
80 struct mesh_path *mpath = ptr; in mesh_path_rht_free() local
83 mesh_path_free_rcu(tbl, mpath); in mesh_path_rht_free()
114 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) in mesh_path_assign_nexthop() argument
120 rcu_assign_pointer(mpath->next_hop, sta); in mesh_path_assign_nexthop()
122 spin_lock_irqsave(&mpath->frame_queue.lock, flags); in mesh_path_assign_nexthop()
123 skb_queue_walk(&mpath->frame_queue, skb) { in mesh_path_assign_nexthop()
126 memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN); in mesh_path_assign_nexthop()
130 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags); in mesh_path_assign_nexthop()
245 struct mesh_path *mpath; in mpath_lookup() local
247 mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params); in mpath_lookup()
249 if (mpath && mpath_expired(mpath)) { in mpath_lookup()
250 spin_lock_bh(&mpath->state_lock); in mpath_lookup()
251 mpath->flags &= ~MESH_PATH_ACTIVE; in mpath_lookup()
252 spin_unlock_bh(&mpath->state_lock); in mpath_lookup()
254 return mpath; in mpath_lookup()
282 struct mesh_path *mpath; in __mesh_path_lookup_by_idx() local
284 hlist_for_each_entry_rcu(mpath, &tbl->walk_head, walk_list) { in __mesh_path_lookup_by_idx()
289 if (!mpath) in __mesh_path_lookup_by_idx()
292 if (mpath_expired(mpath)) { in __mesh_path_lookup_by_idx()
293 spin_lock_bh(&mpath->state_lock); in __mesh_path_lookup_by_idx()
294 mpath->flags &= ~MESH_PATH_ACTIVE; in __mesh_path_lookup_by_idx()
295 spin_unlock_bh(&mpath->state_lock); in __mesh_path_lookup_by_idx()
297 return mpath; in __mesh_path_lookup_by_idx()
334 int mesh_path_add_gate(struct mesh_path *mpath) in mesh_path_add_gate() argument
340 tbl = &mpath->sdata->u.mesh.mesh_paths; in mesh_path_add_gate()
342 spin_lock_bh(&mpath->state_lock); in mesh_path_add_gate()
343 if (mpath->is_gate) { in mesh_path_add_gate()
345 spin_unlock_bh(&mpath->state_lock); in mesh_path_add_gate()
348 mpath->is_gate = true; in mesh_path_add_gate()
349 mpath->sdata->u.mesh.num_gates++; in mesh_path_add_gate()
352 hlist_add_head_rcu(&mpath->gate_list, &tbl->known_gates); in mesh_path_add_gate()
355 spin_unlock_bh(&mpath->state_lock); in mesh_path_add_gate()
357 mpath_dbg(mpath->sdata, in mesh_path_add_gate()
359 mpath->dst, mpath->sdata->u.mesh.num_gates); in mesh_path_add_gate()
371 static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) in mesh_gate_del() argument
373 lockdep_assert_held(&mpath->state_lock); in mesh_gate_del()
374 if (!mpath->is_gate) in mesh_gate_del()
377 mpath->is_gate = false; in mesh_gate_del()
379 hlist_del_rcu(&mpath->gate_list); in mesh_gate_del()
380 mpath->sdata->u.mesh.num_gates--; in mesh_gate_del()
383 mpath_dbg(mpath->sdata, in mesh_gate_del()
385 mpath->dst, mpath->sdata->u.mesh.num_gates); in mesh_gate_del()
440 if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || in mesh_fast_tx_get()
441 mpath_expired(entry->mpath)) { in mesh_fast_tx_get()
450 mesh_path_refresh(sdata, entry->mpath, NULL); in mesh_fast_tx_get()
459 struct sk_buff *skb, struct mesh_path *mpath) in mesh_fast_tx_cache() argument
484 sta = rcu_dereference(mpath->next_hop); in mesh_fast_tx_cache()
498 mppath = mpath; in mesh_fast_tx_cache()
557 build.mpath = mpath; in mesh_fast_tx_cache()
619 void mesh_fast_tx_flush_mpath(struct mesh_path *mpath) in mesh_fast_tx_flush_mpath() argument
621 struct ieee80211_sub_if_data *sdata = mpath->sdata; in mesh_fast_tx_flush_mpath()
628 if (entry->mpath == mpath) in mesh_fast_tx_flush_mpath()
642 if (rcu_access_pointer(entry->mpath->next_hop) == sta) in mesh_fast_tx_flush_sta()
679 struct mesh_path *mpath, *new_mpath; in mesh_path_add() local
697 mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead, in mesh_path_add()
700 if (!mpath) in mesh_path_add()
704 if (mpath) { in mesh_path_add()
707 if (IS_ERR(mpath)) in mesh_path_add()
708 return mpath; in mesh_path_add()
710 new_mpath = mpath; in mesh_path_add()
770 struct mesh_path *mpath; in mesh_plink_broken() local
773 hlist_for_each_entry_rcu(mpath, &tbl->walk_head, walk_list) { in mesh_plink_broken()
774 if (rcu_access_pointer(mpath->next_hop) == sta && in mesh_plink_broken()
775 mpath->flags & MESH_PATH_ACTIVE && in mesh_plink_broken()
776 !(mpath->flags & MESH_PATH_FIXED)) { in mesh_plink_broken()
777 spin_lock_bh(&mpath->state_lock); in mesh_plink_broken()
778 mpath->flags &= ~MESH_PATH_ACTIVE; in mesh_plink_broken()
779 ++mpath->sn; in mesh_plink_broken()
780 spin_unlock_bh(&mpath->state_lock); in mesh_plink_broken()
783 mpath->dst, mpath->sn, in mesh_plink_broken()
791 struct mesh_path *mpath) in mesh_path_free_rcu() argument
793 struct ieee80211_sub_if_data *sdata = mpath->sdata; in mesh_path_free_rcu()
795 spin_lock_bh(&mpath->state_lock); in mesh_path_free_rcu()
796 mpath->flags |= MESH_PATH_RESOLVING | MESH_PATH_DELETED; in mesh_path_free_rcu()
797 mesh_gate_del(tbl, mpath); in mesh_path_free_rcu()
798 spin_unlock_bh(&mpath->state_lock); in mesh_path_free_rcu()
799 timer_shutdown_sync(&mpath->timer); in mesh_path_free_rcu()
802 mesh_path_flush_pending(mpath); in mesh_path_free_rcu()
803 kfree_rcu(mpath, rcu); in mesh_path_free_rcu()
806 static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath) in __mesh_path_del() argument
808 hlist_del_rcu(&mpath->walk_list); in __mesh_path_del()
809 rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); in __mesh_path_del()
810 if (tbl == &mpath->sdata->u.mesh.mpp_paths) in __mesh_path_del()
811 mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst); in __mesh_path_del()
813 mesh_fast_tx_flush_mpath(mpath); in __mesh_path_del()
814 mesh_path_free_rcu(tbl, mpath); in __mesh_path_del()
832 struct mesh_path *mpath; in mesh_path_flush_by_nexthop() local
836 hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { in mesh_path_flush_by_nexthop()
837 if (rcu_access_pointer(mpath->next_hop) == sta) in mesh_path_flush_by_nexthop()
838 __mesh_path_del(tbl, mpath); in mesh_path_flush_by_nexthop()
847 struct mesh_path *mpath; in mpp_flush_by_proxy() local
851 hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { in mpp_flush_by_proxy()
852 if (ether_addr_equal(mpath->mpp, proxy)) in mpp_flush_by_proxy()
853 __mesh_path_del(tbl, mpath); in mpp_flush_by_proxy()
860 struct mesh_path *mpath; in table_flush_by_iface() local
864 hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { in table_flush_by_iface()
865 __mesh_path_del(tbl, mpath); in table_flush_by_iface()
897 struct mesh_path *mpath; in table_path_del() local
900 mpath = rhashtable_lookup_fast(&tbl->rhead, addr, mesh_rht_params); in table_path_del()
901 if (!mpath) { in table_path_del()
906 __mesh_path_del(tbl, mpath); in table_path_del()
940 void mesh_path_tx_pending(struct mesh_path *mpath) in mesh_path_tx_pending() argument
942 if (mpath->flags & MESH_PATH_ACTIVE) in mesh_path_tx_pending()
943 ieee80211_add_pending_skbs(mpath->sdata->local, in mesh_path_tx_pending()
944 &mpath->frame_queue); in mesh_path_tx_pending()
957 int mesh_path_send_to_gates(struct mesh_path *mpath) in mesh_path_send_to_gates() argument
959 struct ieee80211_sub_if_data *sdata = mpath->sdata; in mesh_path_send_to_gates()
961 struct mesh_path *from_mpath = mpath; in mesh_path_send_to_gates()
987 return (from_mpath == mpath) ? -EHOSTUNREACH : 0; in mesh_path_send_to_gates()
1012 void mesh_path_flush_pending(struct mesh_path *mpath) in mesh_path_flush_pending() argument
1014 struct ieee80211_sub_if_data *sdata = mpath->sdata; in mesh_path_flush_pending()
1019 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) in mesh_path_flush_pending()
1020 mesh_path_discard_frame(mpath->sdata, skb); in mesh_path_flush_pending()
1024 if (ether_addr_equal(mpath->dst, preq->dst)) { in mesh_path_flush_pending()
1041 void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) in mesh_path_fix_nexthop() argument
1043 spin_lock_bh(&mpath->state_lock); in mesh_path_fix_nexthop()
1044 mesh_path_assign_nexthop(mpath, next_hop); in mesh_path_fix_nexthop()
1045 mpath->sn = 0xffff; in mesh_path_fix_nexthop()
1046 mpath->metric = 0; in mesh_path_fix_nexthop()
1047 mpath->hop_count = 0; in mesh_path_fix_nexthop()
1048 mpath->exp_time = 0; in mesh_path_fix_nexthop()
1049 mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; in mesh_path_fix_nexthop()
1050 mesh_path_activate(mpath); in mesh_path_fix_nexthop()
1051 mesh_fast_tx_flush_mpath(mpath); in mesh_path_fix_nexthop()
1052 spin_unlock_bh(&mpath->state_lock); in mesh_path_fix_nexthop()
1056 mesh_path_tx_pending(mpath); in mesh_path_fix_nexthop()
1070 struct mesh_path *mpath; in mesh_path_tbl_expire() local
1074 hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) { in mesh_path_tbl_expire()
1075 if ((!(mpath->flags & MESH_PATH_RESOLVING)) && in mesh_path_tbl_expire()
1076 (!(mpath->flags & MESH_PATH_FIXED)) && in mesh_path_tbl_expire()
1077 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) in mesh_path_tbl_expire()
1078 __mesh_path_del(tbl, mpath); in mesh_path_tbl_expire()