Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab1c7906 authored by Henning Rogge's avatar Henning Rogge Committed by Johannes Berg
Browse files

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: default avatarBob Copeland <me@bobcopeland.com>
Signed-off-by: default avatarHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent bf5a70e1
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -940,6 +940,46 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
	return err;
	return err;
}
}


/**
 * 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
 * mesh_path_tx_pending - sends pending frames in a mesh path queue
 *
 *
@@ -1154,6 +1194,17 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
		     time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
		     time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
			mesh_path_del(mpath->sdata, mpath->dst);
			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();
	rcu_read_unlock();
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -2311,6 +2311,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
			spin_lock_bh(&mppath->state_lock);
			spin_lock_bh(&mppath->state_lock);
			if (!ether_addr_equal(mppath->mpp, mpp_addr))
			if (!ether_addr_equal(mppath->mpp, mpp_addr))
				memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
				memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
			mppath->exp_time = jiffies;
			spin_unlock_bh(&mppath->state_lock);
			spin_unlock_bh(&mppath->state_lock);
		}
		}
		rcu_read_unlock();
		rcu_read_unlock();
+4 −1
Original line number Original line Diff line number Diff line
@@ -2173,8 +2173,11 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
					mpp_lookup = true;
					mpp_lookup = true;
			}
			}


			if (mpp_lookup)
			if (mpp_lookup) {
				mppath = mpp_path_lookup(sdata, skb->data);
				mppath = mpp_path_lookup(sdata, skb->data);
				if (mppath)
					mppath->exp_time = jiffies;
			}


			if (mppath && mpath)
			if (mppath && mpath)
				mesh_path_del(mpath->sdata, mpath->dst);
				mesh_path_del(mpath->sdata, mpath->dst);