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

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

mac80211: implement cfg80211_ops to query mesh proxy path table



Implement get_mpp and dump_mpp cfg80211_ops to export the content of the
802.11s mesh proxy path table to userspace.

Signed-off-by: default avatarHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 66be7d2b
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -1516,6 +1516,57 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
	return 0;
}

static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp,
			  struct mpath_info *pinfo)
{
	memset(pinfo, 0, sizeof(*pinfo));
	memcpy(mpp, mpath->mpp, ETH_ALEN);

	pinfo->generation = mpp_paths_generation;
}

static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
			     u8 *dst, u8 *mpp, struct mpath_info *pinfo)

{
	struct ieee80211_sub_if_data *sdata;
	struct mesh_path *mpath;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	rcu_read_lock();
	mpath = mpp_path_lookup(sdata, dst);
	if (!mpath) {
		rcu_read_unlock();
		return -ENOENT;
	}
	memcpy(dst, mpath->dst, ETH_ALEN);
	mpp_set_pinfo(mpath, mpp, pinfo);
	rcu_read_unlock();
	return 0;
}

static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev,
			      int idx, u8 *dst, u8 *mpp,
			      struct mpath_info *pinfo)
{
	struct ieee80211_sub_if_data *sdata;
	struct mesh_path *mpath;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	rcu_read_lock();
	mpath = mpp_path_lookup_by_idx(sdata, idx);
	if (!mpath) {
		rcu_read_unlock();
		return -ENOENT;
	}
	memcpy(dst, mpath->dst, ETH_ALEN);
	mpp_set_pinfo(mpath, mpp, pinfo);
	rcu_read_unlock();
	return 0;
}

static int ieee80211_get_mesh_config(struct wiphy *wiphy,
				struct net_device *dev,
				struct mesh_config *conf)
@@ -3547,6 +3598,8 @@ const struct cfg80211_ops mac80211_config_ops = {
	.change_mpath = ieee80211_change_mpath,
	.get_mpath = ieee80211_get_mpath,
	.dump_mpath = ieee80211_dump_mpath,
	.get_mpp = ieee80211_get_mpp,
	.dump_mpp = ieee80211_dump_mpp,
	.update_mesh_config = ieee80211_update_mesh_config,
	.get_mesh_config = ieee80211_get_mesh_config,
	.join_mesh = ieee80211_join_mesh,
+3 −0
Original line number Diff line number Diff line
@@ -270,6 +270,8 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
		 const u8 *dst, const u8 *mpp);
struct mesh_path *
mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
struct mesh_path *
mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
@@ -317,6 +319,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);

bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
extern int mesh_paths_generation;
extern int mpp_paths_generation;

#ifdef CONFIG_MAC80211_MESH
static inline
+31 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ static struct mesh_table __rcu *mesh_paths;
static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */

int mesh_paths_generation;
int mpp_paths_generation;

/* This lock will have the grow table function as writer and add / delete nodes
 * as readers. RCU provides sufficient protection only when reading the table
@@ -409,6 +410,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
	return NULL;
}

/**
 * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index
 * @idx: index
 * @sdata: local subif, or NULL for all entries
 *
 * Returns: pointer to the proxy path structure, or NULL if not found.
 *
 * Locking: must be called within a read rcu section.
 */
struct mesh_path *
mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
{
	struct mesh_table *tbl = rcu_dereference(mpp_paths);
	struct mpath_node *node;
	int i;
	int j = 0;

	for_each_mesh_entry(tbl, node, i) {
		if (sdata && node->mpath->sdata != sdata)
			continue;
		if (j++ == idx)
			return node->mpath;
	}

	return NULL;
}

/**
 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
 * @mpath: gate path to add to table
@@ -691,6 +719,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,

	spin_unlock(&tbl->hashwlock[hash_idx]);
	read_unlock_bh(&pathtbl_resize_lock);

	mpp_paths_generation++;

	if (grow) {
		set_bit(MESH_WORK_GROW_MPP_TABLE,  &ifmsh->wrkq_flags);
		ieee80211_queue_work(&local->hw, &sdata->work);