aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/mesh.h4
-rw-r--r--net/mac80211/mesh_hwmp.c8
-rw-r--r--net/mac80211/mesh_pathtbl.c24
4 files changed, 11 insertions, 27 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 69238fa67bf2..6b183a3526b0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -785,7 +785,7 @@ static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
785 u8 *dst) 785 u8 *dst)
786{ 786{
787 if (dst) 787 if (dst)
788 return mesh_path_del(dst, dev, false); 788 return mesh_path_del(dst, dev);
789 789
790 mesh_path_flush(dev); 790 mesh_path_flush(dev);
791 return 0; 791 return 0;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index add9b0ddda81..742003d3a841 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -30,7 +30,6 @@
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_DELETE: the mesh path is scheduled to be deleted
34 * 33 *
35 * MESH_PATH_RESOLVED and MESH_PATH_DELETE are used by the mesh path timer to 34 * MESH_PATH_RESOLVED and MESH_PATH_DELETE are used by the mesh path timer to
36 * decide when to stop or cancel the mesh path discovery. 35 * decide when to stop or cancel the mesh path discovery.
@@ -41,7 +40,6 @@ enum mesh_path_flags {
41 MESH_PATH_DSN_VALID = BIT(2), 40 MESH_PATH_DSN_VALID = BIT(2),
42 MESH_PATH_FIXED = BIT(3), 41 MESH_PATH_FIXED = BIT(3),
43 MESH_PATH_RESOLVED = BIT(4), 42 MESH_PATH_RESOLVED = BIT(4),
44 MESH_PATH_DELETE = BIT(5),
45}; 43};
46 44
47/** 45/**
@@ -254,7 +252,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath);
254void mesh_path_tx_pending(struct mesh_path *mpath); 252void mesh_path_tx_pending(struct mesh_path *mpath);
255int mesh_pathtbl_init(void); 253int mesh_pathtbl_init(void);
256void mesh_pathtbl_unregister(void); 254void mesh_pathtbl_unregister(void);
257int mesh_path_del(u8 *addr, struct net_device *dev, bool force); 255int mesh_path_del(u8 *addr, struct net_device *dev);
258void mesh_path_timer(unsigned long data); 256void mesh_path_timer(unsigned long data);
259void mesh_path_flush_by_nexthop(struct sta_info *sta); 257void mesh_path_flush_by_nexthop(struct sta_info *sta);
260void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); 258void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index c8c7d9aa4b94..324ebea10c4c 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -828,7 +828,6 @@ void mesh_path_timer(unsigned long data)
828{ 828{
829 struct ieee80211_sub_if_data *sdata; 829 struct ieee80211_sub_if_data *sdata;
830 struct mesh_path *mpath; 830 struct mesh_path *mpath;
831 bool delete = false;
832 831
833 rcu_read_lock(); 832 rcu_read_lock();
834 mpath = (struct mesh_path *) data; 833 mpath = (struct mesh_path *) data;
@@ -837,10 +836,7 @@ void mesh_path_timer(unsigned long data)
837 goto endmpathtimer; 836 goto endmpathtimer;
838 spin_lock_bh(&mpath->state_lock); 837 spin_lock_bh(&mpath->state_lock);
839 sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev); 838 sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev);
840 if (mpath->flags & MESH_PATH_DELETE) { 839 if (mpath->flags & MESH_PATH_RESOLVED ||
841 mpath->flags = 0;
842 delete = true;
843 } else if (mpath->flags & MESH_PATH_RESOLVED ||
844 (!(mpath->flags & MESH_PATH_RESOLVING))) 840 (!(mpath->flags & MESH_PATH_RESOLVING)))
845 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); 841 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
846 else if (mpath->discovery_retries < max_preq_retries(sdata)) { 842 else if (mpath->discovery_retries < max_preq_retries(sdata)) {
@@ -856,6 +852,4 @@ void mesh_path_timer(unsigned long data)
856 spin_unlock_bh(&mpath->state_lock); 852 spin_unlock_bh(&mpath->state_lock);
857endmpathtimer: 853endmpathtimer:
858 rcu_read_unlock(); 854 rcu_read_unlock();
859 if (delete)
860 mesh_path_del(mpath->dst, mpath->dev, false);
861} 855}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index bd58849f9dfb..f74e4ce40ec7 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -277,7 +277,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
277 for_each_mesh_entry(mesh_paths, p, node, i) { 277 for_each_mesh_entry(mesh_paths, p, node, i) {
278 mpath = node->mpath; 278 mpath = node->mpath;
279 if (mpath->next_hop == sta) 279 if (mpath->next_hop == sta)
280 mesh_path_del(mpath->dst, mpath->dev, true); 280 mesh_path_del(mpath->dst, mpath->dev);
281 } 281 }
282} 282}
283 283
@@ -291,7 +291,7 @@ void mesh_path_flush(struct net_device *dev)
291 for_each_mesh_entry(mesh_paths, p, node, i) { 291 for_each_mesh_entry(mesh_paths, p, node, i) {
292 mpath = node->mpath; 292 mpath = node->mpath;
293 if (mpath->dev == dev) 293 if (mpath->dev == dev)
294 mesh_path_del(mpath->dst, mpath->dev, false); 294 mesh_path_del(mpath->dst, mpath->dev);
295 } 295 }
296} 296}
297 297
@@ -314,12 +314,8 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
314 * @dev: local interface 314 * @dev: local interface
315 * 315 *
316 * Returns: 0 if succesful 316 * Returns: 0 if succesful
317 *
318 * State: if the path is being resolved, the deletion will be postponed until
319 * the path resolution completes or times out, unless the force parameter
320 * is given.
321 */ 317 */
322int mesh_path_del(u8 *addr, struct net_device *dev, bool force) 318int mesh_path_del(u8 *addr, struct net_device *dev)
323{ 319{
324 struct mesh_path *mpath; 320 struct mesh_path *mpath;
325 struct mpath_node *node; 321 struct mpath_node *node;
@@ -338,14 +334,10 @@ int mesh_path_del(u8 *addr, struct net_device *dev, bool force)
338 if (mpath->dev == dev && 334 if (mpath->dev == dev &&
339 memcmp(addr, mpath->dst, ETH_ALEN) == 0) { 335 memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
340 spin_lock_bh(&mpath->state_lock); 336 spin_lock_bh(&mpath->state_lock);
341 if (!force && mpath->flags & MESH_PATH_RESOLVING) { 337 mpath->flags |= MESH_PATH_RESOLVING;
342 mpath->flags |= MESH_PATH_DELETE; 338 hlist_del_rcu(&node->list);
343 } else { 339 call_rcu(&node->rcu, mesh_path_node_reclaim);
344 mpath->flags |= MESH_PATH_RESOLVING; 340 atomic_dec(&mesh_paths->entries);
345 hlist_del_rcu(&node->list);
346 call_rcu(&node->rcu, mesh_path_node_reclaim);
347 atomic_dec(&mesh_paths->entries);
348 }
349 spin_unlock_bh(&mpath->state_lock); 341 spin_unlock_bh(&mpath->state_lock);
350 goto enddel; 342 goto enddel;
351 } 343 }
@@ -508,7 +500,7 @@ void mesh_path_expire(struct net_device *dev)
508 time_after(jiffies, 500 time_after(jiffies,
509 mpath->exp_time + MESH_PATH_EXPIRE)) { 501 mpath->exp_time + MESH_PATH_EXPIRE)) {
510 spin_unlock_bh(&mpath->state_lock); 502 spin_unlock_bh(&mpath->state_lock);
511 mesh_path_del(mpath->dst, mpath->dev, false); 503 mesh_path_del(mpath->dst, mpath->dev);
512 } else 504 } else
513 spin_unlock_bh(&mpath->state_lock); 505 spin_unlock_bh(&mpath->state_lock);
514 } 506 }