diff options
Diffstat (limited to 'package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch')
-rw-r--r-- | package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch b/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch new file mode 100644 index 0000000..740993c --- /dev/null +++ b/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch @@ -0,0 +1,104 @@ +From: Henning Rogge <hrogge@gmail.com> +Date: Wed, 3 Feb 2016 13:58:37 +0100 +Subject: [PATCH] mac80211: let unused MPP table entries timeout + +Remember the last time when a mpp table entry is used for +rx or tx and remove them after MESH_PATH_EXPIRE time. + +Acked-by: Bob Copeland <me@bobcopeland.com> +Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -942,6 +942,46 @@ enddel: + } + + /** ++ * mpp_path_del - delete a mesh proxy path from the table ++ * ++ * @addr: addr address (ETH_ALEN length) ++ * @sdata: local subif ++ * ++ * Returns: 0 if successful ++ */ ++static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) ++{ ++ struct mesh_table *tbl; ++ struct mesh_path *mpath; ++ struct mpath_node *node; ++ struct hlist_head *bucket; ++ int hash_idx; ++ int err = 0; ++ ++ read_lock_bh(&pathtbl_resize_lock); ++ tbl = resize_dereference_mpp_paths(); ++ hash_idx = mesh_table_hash(addr, sdata, tbl); ++ bucket = &tbl->hash_buckets[hash_idx]; ++ ++ spin_lock(&tbl->hashwlock[hash_idx]); ++ hlist_for_each_entry(node, bucket, list) { ++ mpath = node->mpath; ++ if (mpath->sdata == sdata && ++ ether_addr_equal(addr, mpath->dst)) { ++ __mesh_path_del(tbl, node); ++ goto enddel; ++ } ++ } ++ ++ err = -ENXIO; ++enddel: ++ mesh_paths_generation++; ++ spin_unlock(&tbl->hashwlock[hash_idx]); ++ read_unlock_bh(&pathtbl_resize_lock); ++ return err; ++} ++ ++/** + * mesh_path_tx_pending - sends pending frames in a mesh path queue + * + * @mpath: mesh path to activate +@@ -1157,6 +1197,17 @@ void mesh_path_expire(struct ieee80211_s + time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) + mesh_path_del(mpath->sdata, mpath->dst); + } ++ ++ tbl = rcu_dereference(mpp_paths); ++ for_each_mesh_entry(tbl, node, i) { ++ if (node->mpath->sdata != sdata) ++ continue; ++ mpath = node->mpath; ++ if ((!(mpath->flags & MESH_PATH_FIXED)) && ++ time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) ++ mpp_path_del(mpath->sdata, mpath->dst); ++ } ++ + rcu_read_unlock(); + } + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2291,6 +2291,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + spin_lock_bh(&mppath->state_lock); + if (!ether_addr_equal(mppath->mpp, mpp_addr)) + memcpy(mppath->mpp, mpp_addr, ETH_ALEN); ++ mppath->exp_time = jiffies; + spin_unlock_bh(&mppath->state_lock); + } + rcu_read_unlock(); +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -2171,8 +2171,11 @@ static struct sk_buff *ieee80211_build_h + mpp_lookup = true; + } + +- if (mpp_lookup) ++ if (mpp_lookup) { + mppath = mpp_path_lookup(sdata, skb->data); ++ if (mppath) ++ mppath->exp_time = jiffies; ++ } + + if (mppath && mpath) + mesh_path_del(mpath->sdata, mpath->dst); |