* [Patch]mac80211: Add support for mesh proxy path dump
@ 2014-09-01 11:26 Henning Rogge
2014-09-01 12:03 ` Henning Rogge
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Henning Rogge @ 2014-09-01 11:26 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Johannes Berg, Yeoh Chun-Yeow
The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that
allows to query the content of the 'mesh proxy path' table of mac80211s via
'get' or 'dump' operation.
Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de>
---
include/net/cfg80211.h | 7 ++++
include/uapi/linux/nl80211.h | 6 +++
net/mac80211/cfg.c | 53 ++++++++++++++++++++++++
net/mac80211/mesh.h | 3 ++
net/mac80211/mesh_pathtbl.c | 31 ++++++++++++++
net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 27 +++++++++++-
net/wireless/trace.h | 45 ++++++++++++++++++++
8 files changed, 270 insertions(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0a080c4..68fbcf5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2139,6 +2139,8 @@ struct cfg80211_qos_map {
* @change_mpath: change a given mesh path
* @get_mpath: get a mesh path for the given parameters
* @dump_mpath: dump mesh path callback -- resume dump at index @idx
+ * @get_mpp: get a mesh proxy path for the given parameters
+ * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx
* @join_mesh: join the mesh network with the specified parameters
* (invoked with the wireless_dev mutex held)
* @leave_mesh: leave the current mesh network
@@ -2378,6 +2380,11 @@ struct cfg80211_ops {
int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
int idx, u8 *dst, u8 *next_hop,
struct mpath_info *pinfo);
+ int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev,
+ u8 *dst, u8 *mpp, struct mpath_info *pinfo);
+ int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev,
+ int idx, u8 *dst, u8 *mpp,
+ struct mpath_info *pinfo);
int (*get_mesh_config)(struct wiphy *wiphy,
struct net_device *dev,
struct mesh_config *conf);
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f1db15b..80cff48 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -722,6 +722,10 @@
* QoS mapping is relevant for IP packets, it is only valid during an
* association. This is cleared on disassociation and AP restart.
*
+ * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to
+ * destination %NL80211_ATTR_MAC on the interface identified by
+ * %NL80211_ATTR_IFINDEX.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -893,6 +897,8 @@ enum nl80211_commands {
NL80211_CMD_SET_QOS_MAP,
+ NL80211_CMD_GET_MPP,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 927b4ea..2b85eed 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1511,6 +1511,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)
@@ -3507,6 +3558,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,
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f39a19f..50c8473 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -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
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index cf032a8..8630963 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -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
@@ -410,6 +411,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
}
/**
+ * 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);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index df7b133..1e33f2f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4581,6 +4581,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
return rdev_del_mpath(rdev, dev, dst);
}
+static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ int err;
+ struct net_device *dev = info->user_ptr[1];
+ struct mpath_info pinfo;
+ struct sk_buff *msg;
+ u8 *dst = NULL;
+ u8 mpp[ETH_ALEN];
+
+ memset(&pinfo, 0, sizeof(pinfo));
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+ if (!rdev->ops->get_mpp)
+ return -EOPNOTSUPP;
+
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
+ if (err)
+ return err;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
+ dev, dst, mpp, &pinfo) < 0) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
+
+ return genlmsg_reply(msg, info);
+}
+
+static int nl80211_dump_mpp(struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ struct mpath_info pinfo;
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+ u8 dst[ETH_ALEN];
+ u8 mpp[ETH_ALEN];
+ int path_idx = cb->args[2];
+ int err;
+
+ err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
+ if (err)
+ return err;
+
+ if (!rdev->ops->dump_mpp) {
+ err = -EOPNOTSUPP;
+ goto out_err;
+ }
+
+ if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
+ err = -EOPNOTSUPP;
+ goto out_err;
+ }
+
+ while (1) {
+ err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
+ mpp, &pinfo);
+ if (err == -ENOENT)
+ break;
+ if (err)
+ goto out_err;
+
+ if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ wdev->netdev, dst, mpp,
+ &pinfo) < 0)
+ goto out;
+
+ path_idx++;
+ }
+
+ out:
+ cb->args[2] = path_idx;
+ err = skb->len;
+ out_err:
+ nl80211_finish_wdev_dump(rdev);
+ return err;
+}
+
static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9603,6 +9693,15 @@ static const struct genl_ops nl80211_ops[] = {
NL80211_FLAG_NEED_RTNL,
},
{
+ .cmd = NL80211_CMD_GET_MPP,
+ .doit = nl80211_get_mpp,
+ .dumpit = nl80211_dump_mpp,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
.cmd = NL80211_CMD_SET_MPATH,
.doit = nl80211_set_mpath,
.policy = nl80211_policy,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 56c2240..e5560d5 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev,
}
+static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, u8 *dst, u8 *mpp,
+ struct mpath_info *pinfo)
+{
+ int ret;
+
+ trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp);
+ ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo);
+ trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
+ return ret;
+}
+
static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
struct net_device *dev, int idx, u8 *dst,
u8 *next_hop, struct mpath_info *pinfo)
@@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
int ret;
trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop);
ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop,
- pinfo);
+ pinfo);
+ trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
+ return ret;
+}
+
+static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, int idx, u8 *dst,
+ u8 *mpp, struct mpath_info *pinfo)
+
+{
+ int ret;
+
+ trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp);
+ ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo);
trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
return ret;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 0c524cd..57ab727 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath,
MAC_PR_ARG(next_hop))
);
+TRACE_EVENT(rdev_get_mpp,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ u8 *dst, u8 *mpp),
+ TP_ARGS(wiphy, netdev, dst, mpp),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(dst)
+ MAC_ENTRY(mpp)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(dst, dst);
+ MAC_ASSIGN(mpp, mpp);
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT
+ ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG,
+ MAC_PR_ARG(dst), MAC_PR_ARG(mpp))
+);
+
+TRACE_EVENT(rdev_dump_mpp,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx,
+ u8 *dst, u8 *mpp),
+ TP_ARGS(wiphy, netdev, idx, mpp, dst),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(dst)
+ MAC_ENTRY(mpp)
+ __field(int, idx)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(dst, dst);
+ MAC_ASSIGN(mpp, mpp);
+ __entry->idx = idx;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
+ MAC_PR_FMT ", mpp: " MAC_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
+ MAC_PR_ARG(mpp))
+);
+
TRACE_EVENT(rdev_return_int_mpath_info,
TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo),
TP_ARGS(wiphy, ret, pinfo),
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-01 11:26 [Patch]mac80211: Add support for mesh proxy path dump Henning Rogge @ 2014-09-01 12:03 ` Henning Rogge 2014-09-02 6:29 ` Yeoh Chun-Yeow 2014-09-02 8:03 ` Johannes Berg 2014-09-03 11:52 ` Johannes Berg 2 siblings, 1 reply; 10+ messages in thread From: Henning Rogge @ 2014-09-01 12:03 UTC (permalink / raw) To: linux-wireless@vger.kernel.org; +Cc: Johannes Berg, Yeoh Chun-Yeow Hi, I forgot to add that the patch applies to the head of wireless-testing. I have also tested it on OpenWRT Barrier Breaker on a Ubiquiti Bullet M5 with the ath9k driver. Henning Rogge On Mon, Sep 1, 2014 at 1:26 PM, Henning Rogge <hrogge@gmail.com> wrote: > The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that > allows to query the content of the 'mesh proxy path' table of mac80211s via > 'get' or 'dump' operation. > > Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de> > --- > include/net/cfg80211.h | 7 ++++ > include/uapi/linux/nl80211.h | 6 +++ > net/mac80211/cfg.c | 53 ++++++++++++++++++++++++ > net/mac80211/mesh.h | 3 ++ > net/mac80211/mesh_pathtbl.c | 31 ++++++++++++++ > net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ > net/wireless/rdev-ops.h | 27 +++++++++++- > net/wireless/trace.h | 45 ++++++++++++++++++++ > 8 files changed, 270 insertions(+), 1 deletion(-) > > diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h > index 0a080c4..68fbcf5 100644 > --- a/include/net/cfg80211.h > +++ b/include/net/cfg80211.h > @@ -2139,6 +2139,8 @@ struct cfg80211_qos_map { > * @change_mpath: change a given mesh path > * @get_mpath: get a mesh path for the given parameters > * @dump_mpath: dump mesh path callback -- resume dump at index @idx > + * @get_mpp: get a mesh proxy path for the given parameters > + * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx > * @join_mesh: join the mesh network with the specified parameters > * (invoked with the wireless_dev mutex held) > * @leave_mesh: leave the current mesh network > @@ -2378,6 +2380,11 @@ struct cfg80211_ops { > int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, > int idx, u8 *dst, u8 *next_hop, > struct mpath_info *pinfo); > + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, > + u8 *dst, u8 *mpp, struct mpath_info *pinfo); > + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, > + int idx, u8 *dst, u8 *mpp, > + struct mpath_info *pinfo); > int (*get_mesh_config)(struct wiphy *wiphy, > struct net_device *dev, > struct mesh_config *conf); > diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h > index f1db15b..80cff48 100644 > --- a/include/uapi/linux/nl80211.h > +++ b/include/uapi/linux/nl80211.h > @@ -722,6 +722,10 @@ > * QoS mapping is relevant for IP packets, it is only valid during an > * association. This is cleared on disassociation and AP restart. > * > + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to > + * destination %NL80211_ATTR_MAC on the interface identified by > + * %NL80211_ATTR_IFINDEX. > + * > * @NL80211_CMD_MAX: highest used command number > * @__NL80211_CMD_AFTER_LAST: internal use > */ > @@ -893,6 +897,8 @@ enum nl80211_commands { > > NL80211_CMD_SET_QOS_MAP, > > + NL80211_CMD_GET_MPP, > + > /* add new commands above here */ > > /* used to define NL80211_CMD_MAX below */ > diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c > index 927b4ea..2b85eed 100644 > --- a/net/mac80211/cfg.c > +++ b/net/mac80211/cfg.c > @@ -1511,6 +1511,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) > @@ -3507,6 +3558,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, > diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h > index f39a19f..50c8473 100644 > --- a/net/mac80211/mesh.h > +++ b/net/mac80211/mesh.h > @@ -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 > diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c > index cf032a8..8630963 100644 > --- a/net/mac80211/mesh_pathtbl.c > +++ b/net/mac80211/mesh_pathtbl.c > @@ -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 > @@ -410,6 +411,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) > } > > /** > + * 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); > diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c > index df7b133..1e33f2f 100644 > --- a/net/wireless/nl80211.c > +++ b/net/wireless/nl80211.c > @@ -4581,6 +4581,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) > return rdev_del_mpath(rdev, dev, dst); > } > > +static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) > +{ > + struct cfg80211_registered_device *rdev = info->user_ptr[0]; > + int err; > + struct net_device *dev = info->user_ptr[1]; > + struct mpath_info pinfo; > + struct sk_buff *msg; > + u8 *dst = NULL; > + u8 mpp[ETH_ALEN]; > + > + memset(&pinfo, 0, sizeof(pinfo)); > + > + if (!info->attrs[NL80211_ATTR_MAC]) > + return -EINVAL; > + > + dst = nla_data(info->attrs[NL80211_ATTR_MAC]); > + > + if (!rdev->ops->get_mpp) > + return -EOPNOTSUPP; > + > + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) > + return -EOPNOTSUPP; > + > + err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); > + if (err) > + return err; > + > + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, > + dev, dst, mpp, &pinfo) < 0) { > + nlmsg_free(msg); > + return -ENOBUFS; > + } > + > + return genlmsg_reply(msg, info); > +} > + > +static int nl80211_dump_mpp(struct sk_buff *skb, > + struct netlink_callback *cb) > +{ > + struct mpath_info pinfo; > + struct cfg80211_registered_device *rdev; > + struct wireless_dev *wdev; > + u8 dst[ETH_ALEN]; > + u8 mpp[ETH_ALEN]; > + int path_idx = cb->args[2]; > + int err; > + > + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); > + if (err) > + return err; > + > + if (!rdev->ops->dump_mpp) { > + err = -EOPNOTSUPP; > + goto out_err; > + } > + > + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { > + err = -EOPNOTSUPP; > + goto out_err; > + } > + > + while (1) { > + err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, > + mpp, &pinfo); > + if (err == -ENOENT) > + break; > + if (err) > + goto out_err; > + > + if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, > + cb->nlh->nlmsg_seq, NLM_F_MULTI, > + wdev->netdev, dst, mpp, > + &pinfo) < 0) > + goto out; > + > + path_idx++; > + } > + > + out: > + cb->args[2] = path_idx; > + err = skb->len; > + out_err: > + nl80211_finish_wdev_dump(rdev); > + return err; > +} > + > static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) > { > struct cfg80211_registered_device *rdev = info->user_ptr[0]; > @@ -9603,6 +9693,15 @@ static const struct genl_ops nl80211_ops[] = { > NL80211_FLAG_NEED_RTNL, > }, > { > + .cmd = NL80211_CMD_GET_MPP, > + .doit = nl80211_get_mpp, > + .dumpit = nl80211_dump_mpp, > + .policy = nl80211_policy, > + .flags = GENL_ADMIN_PERM, > + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | > + NL80211_FLAG_NEED_RTNL, > + }, > + { > .cmd = NL80211_CMD_SET_MPATH, > .doit = nl80211_set_mpath, > .policy = nl80211_policy, > diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h > index 56c2240..e5560d5 100644 > --- a/net/wireless/rdev-ops.h > +++ b/net/wireless/rdev-ops.h > @@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, > > } > > +static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, > + struct net_device *dev, u8 *dst, u8 *mpp, > + struct mpath_info *pinfo) > +{ > + int ret; > + > + trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); > + ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); > + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); > + return ret; > +} > + > static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, > struct net_device *dev, int idx, u8 *dst, > u8 *next_hop, struct mpath_info *pinfo) > @@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, > int ret; > trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); > ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, > - pinfo); > + pinfo); > + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); > + return ret; > +} > + > +static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, > + struct net_device *dev, int idx, u8 *dst, > + u8 *mpp, struct mpath_info *pinfo) > + > +{ > + int ret; > + > + trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); > + ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); > trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); > return ret; > } > diff --git a/net/wireless/trace.h b/net/wireless/trace.h > index 0c524cd..57ab727 100644 > --- a/net/wireless/trace.h > +++ b/net/wireless/trace.h > @@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath, > MAC_PR_ARG(next_hop)) > ); > > +TRACE_EVENT(rdev_get_mpp, > + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, > + u8 *dst, u8 *mpp), > + TP_ARGS(wiphy, netdev, dst, mpp), > + TP_STRUCT__entry( > + WIPHY_ENTRY > + NETDEV_ENTRY > + MAC_ENTRY(dst) > + MAC_ENTRY(mpp) > + ), > + TP_fast_assign( > + WIPHY_ASSIGN; > + NETDEV_ASSIGN; > + MAC_ASSIGN(dst, dst); > + MAC_ASSIGN(mpp, mpp); > + ), > + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT > + ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, > + MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) > +); > + > +TRACE_EVENT(rdev_dump_mpp, > + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, > + u8 *dst, u8 *mpp), > + TP_ARGS(wiphy, netdev, idx, mpp, dst), > + TP_STRUCT__entry( > + WIPHY_ENTRY > + NETDEV_ENTRY > + MAC_ENTRY(dst) > + MAC_ENTRY(mpp) > + __field(int, idx) > + ), > + TP_fast_assign( > + WIPHY_ASSIGN; > + NETDEV_ASSIGN; > + MAC_ASSIGN(dst, dst); > + MAC_ASSIGN(mpp, mpp); > + __entry->idx = idx; > + ), > + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " > + MAC_PR_FMT ", mpp: " MAC_PR_FMT, > + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), > + MAC_PR_ARG(mpp)) > +); > + > TRACE_EVENT(rdev_return_int_mpath_info, > TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), > TP_ARGS(wiphy, ret, pinfo), > -- > 1.9.1 > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-01 12:03 ` Henning Rogge @ 2014-09-02 6:29 ` Yeoh Chun-Yeow 0 siblings, 0 replies; 10+ messages in thread From: Yeoh Chun-Yeow @ 2014-09-02 6:29 UTC (permalink / raw) To: Henning Rogge; +Cc: linux-wireless@vger.kernel.org, Johannes Berg Tested with ath9k and working fine for me. ---- ChunYeow On Mon, Sep 1, 2014 at 8:03 PM, Henning Rogge <hrogge@gmail.com> wrote: > Hi, > > I forgot to add that the patch applies to the head of > wireless-testing. I have also tested it on OpenWRT Barrier Breaker on > a Ubiquiti Bullet M5 with the ath9k driver. > > Henning Rogge > > On Mon, Sep 1, 2014 at 1:26 PM, Henning Rogge <hrogge@gmail.com> wrote: >> The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that >> allows to query the content of the 'mesh proxy path' table of mac80211s via >> 'get' or 'dump' operation. >> >> Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de> >> --- >> include/net/cfg80211.h | 7 ++++ >> include/uapi/linux/nl80211.h | 6 +++ >> net/mac80211/cfg.c | 53 ++++++++++++++++++++++++ >> net/mac80211/mesh.h | 3 ++ >> net/mac80211/mesh_pathtbl.c | 31 ++++++++++++++ >> net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++ >> net/wireless/rdev-ops.h | 27 +++++++++++- >> net/wireless/trace.h | 45 ++++++++++++++++++++ >> 8 files changed, 270 insertions(+), 1 deletion(-) >> >> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h >> index 0a080c4..68fbcf5 100644 >> --- a/include/net/cfg80211.h >> +++ b/include/net/cfg80211.h >> @@ -2139,6 +2139,8 @@ struct cfg80211_qos_map { >> * @change_mpath: change a given mesh path >> * @get_mpath: get a mesh path for the given parameters >> * @dump_mpath: dump mesh path callback -- resume dump at index @idx >> + * @get_mpp: get a mesh proxy path for the given parameters >> + * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx >> * @join_mesh: join the mesh network with the specified parameters >> * (invoked with the wireless_dev mutex held) >> * @leave_mesh: leave the current mesh network >> @@ -2378,6 +2380,11 @@ struct cfg80211_ops { >> int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, >> int idx, u8 *dst, u8 *next_hop, >> struct mpath_info *pinfo); >> + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, >> + u8 *dst, u8 *mpp, struct mpath_info *pinfo); >> + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, >> + int idx, u8 *dst, u8 *mpp, >> + struct mpath_info *pinfo); >> int (*get_mesh_config)(struct wiphy *wiphy, >> struct net_device *dev, >> struct mesh_config *conf); >> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h >> index f1db15b..80cff48 100644 >> --- a/include/uapi/linux/nl80211.h >> +++ b/include/uapi/linux/nl80211.h >> @@ -722,6 +722,10 @@ >> * QoS mapping is relevant for IP packets, it is only valid during an >> * association. This is cleared on disassociation and AP restart. >> * >> + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to >> + * destination %NL80211_ATTR_MAC on the interface identified by >> + * %NL80211_ATTR_IFINDEX. >> + * >> * @NL80211_CMD_MAX: highest used command number >> * @__NL80211_CMD_AFTER_LAST: internal use >> */ >> @@ -893,6 +897,8 @@ enum nl80211_commands { >> >> NL80211_CMD_SET_QOS_MAP, >> >> + NL80211_CMD_GET_MPP, >> + >> /* add new commands above here */ >> >> /* used to define NL80211_CMD_MAX below */ >> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c >> index 927b4ea..2b85eed 100644 >> --- a/net/mac80211/cfg.c >> +++ b/net/mac80211/cfg.c >> @@ -1511,6 +1511,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) >> @@ -3507,6 +3558,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, >> diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h >> index f39a19f..50c8473 100644 >> --- a/net/mac80211/mesh.h >> +++ b/net/mac80211/mesh.h >> @@ -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 >> diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c >> index cf032a8..8630963 100644 >> --- a/net/mac80211/mesh_pathtbl.c >> +++ b/net/mac80211/mesh_pathtbl.c >> @@ -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 >> @@ -410,6 +411,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) >> } >> >> /** >> + * 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); >> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c >> index df7b133..1e33f2f 100644 >> --- a/net/wireless/nl80211.c >> +++ b/net/wireless/nl80211.c >> @@ -4581,6 +4581,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) >> return rdev_del_mpath(rdev, dev, dst); >> } >> >> +static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) >> +{ >> + struct cfg80211_registered_device *rdev = info->user_ptr[0]; >> + int err; >> + struct net_device *dev = info->user_ptr[1]; >> + struct mpath_info pinfo; >> + struct sk_buff *msg; >> + u8 *dst = NULL; >> + u8 mpp[ETH_ALEN]; >> + >> + memset(&pinfo, 0, sizeof(pinfo)); >> + >> + if (!info->attrs[NL80211_ATTR_MAC]) >> + return -EINVAL; >> + >> + dst = nla_data(info->attrs[NL80211_ATTR_MAC]); >> + >> + if (!rdev->ops->get_mpp) >> + return -EOPNOTSUPP; >> + >> + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) >> + return -EOPNOTSUPP; >> + >> + err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); >> + if (err) >> + return err; >> + >> + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); >> + if (!msg) >> + return -ENOMEM; >> + >> + if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, >> + dev, dst, mpp, &pinfo) < 0) { >> + nlmsg_free(msg); >> + return -ENOBUFS; >> + } >> + >> + return genlmsg_reply(msg, info); >> +} >> + >> +static int nl80211_dump_mpp(struct sk_buff *skb, >> + struct netlink_callback *cb) >> +{ >> + struct mpath_info pinfo; >> + struct cfg80211_registered_device *rdev; >> + struct wireless_dev *wdev; >> + u8 dst[ETH_ALEN]; >> + u8 mpp[ETH_ALEN]; >> + int path_idx = cb->args[2]; >> + int err; >> + >> + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); >> + if (err) >> + return err; >> + >> + if (!rdev->ops->dump_mpp) { >> + err = -EOPNOTSUPP; >> + goto out_err; >> + } >> + >> + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { >> + err = -EOPNOTSUPP; >> + goto out_err; >> + } >> + >> + while (1) { >> + err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, >> + mpp, &pinfo); >> + if (err == -ENOENT) >> + break; >> + if (err) >> + goto out_err; >> + >> + if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, >> + cb->nlh->nlmsg_seq, NLM_F_MULTI, >> + wdev->netdev, dst, mpp, >> + &pinfo) < 0) >> + goto out; >> + >> + path_idx++; >> + } >> + >> + out: >> + cb->args[2] = path_idx; >> + err = skb->len; >> + out_err: >> + nl80211_finish_wdev_dump(rdev); >> + return err; >> +} >> + >> static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) >> { >> struct cfg80211_registered_device *rdev = info->user_ptr[0]; >> @@ -9603,6 +9693,15 @@ static const struct genl_ops nl80211_ops[] = { >> NL80211_FLAG_NEED_RTNL, >> }, >> { >> + .cmd = NL80211_CMD_GET_MPP, >> + .doit = nl80211_get_mpp, >> + .dumpit = nl80211_dump_mpp, >> + .policy = nl80211_policy, >> + .flags = GENL_ADMIN_PERM, >> + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | >> + NL80211_FLAG_NEED_RTNL, >> + }, >> + { >> .cmd = NL80211_CMD_SET_MPATH, >> .doit = nl80211_set_mpath, >> .policy = nl80211_policy, >> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h >> index 56c2240..e5560d5 100644 >> --- a/net/wireless/rdev-ops.h >> +++ b/net/wireless/rdev-ops.h >> @@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, >> >> } >> >> +static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, >> + struct net_device *dev, u8 *dst, u8 *mpp, >> + struct mpath_info *pinfo) >> +{ >> + int ret; >> + >> + trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); >> + ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); >> + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); >> + return ret; >> +} >> + >> static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, >> struct net_device *dev, int idx, u8 *dst, >> u8 *next_hop, struct mpath_info *pinfo) >> @@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, >> int ret; >> trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); >> ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, >> - pinfo); >> + pinfo); >> + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); >> + return ret; >> +} >> + >> +static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, >> + struct net_device *dev, int idx, u8 *dst, >> + u8 *mpp, struct mpath_info *pinfo) >> + >> +{ >> + int ret; >> + >> + trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); >> + ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); >> trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); >> return ret; >> } >> diff --git a/net/wireless/trace.h b/net/wireless/trace.h >> index 0c524cd..57ab727 100644 >> --- a/net/wireless/trace.h >> +++ b/net/wireless/trace.h >> @@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath, >> MAC_PR_ARG(next_hop)) >> ); >> >> +TRACE_EVENT(rdev_get_mpp, >> + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, >> + u8 *dst, u8 *mpp), >> + TP_ARGS(wiphy, netdev, dst, mpp), >> + TP_STRUCT__entry( >> + WIPHY_ENTRY >> + NETDEV_ENTRY >> + MAC_ENTRY(dst) >> + MAC_ENTRY(mpp) >> + ), >> + TP_fast_assign( >> + WIPHY_ASSIGN; >> + NETDEV_ASSIGN; >> + MAC_ASSIGN(dst, dst); >> + MAC_ASSIGN(mpp, mpp); >> + ), >> + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT >> + ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, >> + MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) >> +); >> + >> +TRACE_EVENT(rdev_dump_mpp, >> + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, >> + u8 *dst, u8 *mpp), >> + TP_ARGS(wiphy, netdev, idx, mpp, dst), >> + TP_STRUCT__entry( >> + WIPHY_ENTRY >> + NETDEV_ENTRY >> + MAC_ENTRY(dst) >> + MAC_ENTRY(mpp) >> + __field(int, idx) >> + ), >> + TP_fast_assign( >> + WIPHY_ASSIGN; >> + NETDEV_ASSIGN; >> + MAC_ASSIGN(dst, dst); >> + MAC_ASSIGN(mpp, mpp); >> + __entry->idx = idx; >> + ), >> + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " >> + MAC_PR_FMT ", mpp: " MAC_PR_FMT, >> + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), >> + MAC_PR_ARG(mpp)) >> +); >> + >> TRACE_EVENT(rdev_return_int_mpath_info, >> TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), >> TP_ARGS(wiphy, ret, pinfo), >> -- >> 1.9.1 >> >> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-01 11:26 [Patch]mac80211: Add support for mesh proxy path dump Henning Rogge 2014-09-01 12:03 ` Henning Rogge @ 2014-09-02 8:03 ` Johannes Berg 2014-09-02 8:15 ` Henning Rogge 2014-09-03 11:52 ` Johannes Berg 2 siblings, 1 reply; 10+ messages in thread From: Johannes Berg @ 2014-09-02 8:03 UTC (permalink / raw) To: Henning Rogge; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Mon, 2014-09-01 at 13:26 +0200, Henning Rogge wrote: > The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that > allows to query the content of the 'mesh proxy path' table of mac80211s via > 'get' or 'dump' operation. Is this really something that should be a generic nl80211 operation, rather than say debugfs? Could this be useful to other devices implementing the 11s, or is it more of a mac80211 implementation detail? johannes ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-02 8:03 ` Johannes Berg @ 2014-09-02 8:15 ` Henning Rogge 0 siblings, 0 replies; 10+ messages in thread From: Henning Rogge @ 2014-09-02 8:15 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Tue, Sep 2, 2014 at 10:03 AM, Johannes Berg <johannes@sipsolutions.net> wrote: > On Mon, 2014-09-01 at 13:26 +0200, Henning Rogge wrote: >> The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that >> allows to query the content of the 'mesh proxy path' table of mac80211s via >> 'get' or 'dump' operation. > > Is this really something that should be a generic nl80211 operation, > rather than say debugfs? No, this should be (in my opinion) a nl80211 operation. It is directly comparable to "station get/dump" and "mpath get/dump". > Could this be useful to other devices implementing the 11s, or is it > more of a mac80211 implementation detail? Yes, this could be relevant to all 11s implementations. Without this data you cannot determine where your data packages will be going (similar to the routing table/fib, just layer-2). In my case I need this feature to correlate the layer-2 data I got from a "station dump" with the mac addresses of bridged devices. I am trying to implement a DLEP-style radio/router system (see http://tools.ietf.org/html/draft-ietf-manet-dlep-06), which combines a IP router with a bridged radio (both connected via ethernet). The routers can talk directly to each other, but to map the layer-2 data from the radio (which refers to the wifi MAC addresses) to the router communication, I need the mapping table. Henning Rogge ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-01 11:26 [Patch]mac80211: Add support for mesh proxy path dump Henning Rogge 2014-09-01 12:03 ` Henning Rogge 2014-09-02 8:03 ` Johannes Berg @ 2014-09-03 11:52 ` Johannes Berg 2014-09-03 12:12 ` Henning Rogge 2 siblings, 1 reply; 10+ messages in thread From: Johannes Berg @ 2014-09-03 11:52 UTC (permalink / raw) To: Henning Rogge; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Mon, 2014-09-01 at 13:26 +0200, Henning Rogge wrote: > The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that > allows to query the content of the 'mesh proxy path' table of mac80211s via > 'get' or 'dump' operation. For review and merging, and to make it more obvious to you as well when writing commit logs/documentation/etc I'd prefer if you'd split this up into separate cfg80211 and mac80211 patches. > + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, > + u8 *dst, u8 *mpp, struct mpath_info *pinfo); > + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, > + int idx, u8 *dst, u8 *mpp, > + struct mpath_info *pinfo); Should dst/mpp be const? Or are those output parameters? Should it really be mpath_info? I thought this was some other thing? Probably just need more documentation :) johannes ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-03 11:52 ` Johannes Berg @ 2014-09-03 12:12 ` Henning Rogge 2014-09-03 12:25 ` Johannes Berg 0 siblings, 1 reply; 10+ messages in thread From: Henning Rogge @ 2014-09-03 12:12 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Wed, Sep 3, 2014 at 1:52 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > On Mon, 2014-09-01 at 13:26 +0200, Henning Rogge wrote: >> The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that >> allows to query the content of the 'mesh proxy path' table of mac80211s via >> 'get' or 'dump' operation. > > For review and merging, and to make it more obvious to you as well when > writing commit logs/documentation/etc I'd prefer if you'd split this up > into separate cfg80211 and mac80211 patches. Just to make sure I got the split right... First patch to define the two new cfg80211_ops and the necessary nl80211/tracing helper functions, second patch that implements get_mpp() and dump_mpp() functions? >> + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, >> + u8 *dst, u8 *mpp, struct mpath_info *pinfo); >> + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, >> + int idx, u8 *dst, u8 *mpp, >> + struct mpath_info *pinfo); > > Should dst/mpp be const? Or are those output parameters? Yes, similar to the get_mpath/dump_mpath cfg80211_ops these are output parameters. Same thing for pinfo. > Should it really be mpath_info? I thought this was some other thing? > Probably just need more documentation :) mpath and mpp use the same storage object (struct mesh_path), so I reused the mpath_info struct. As far as I can see its just a "transfer object" between for cfg80211 that temporarily stores data from the cfg80211_ops for nl80211 messages. Shall I create a new struct for the two new cfg80211_ops? See ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-03 12:12 ` Henning Rogge @ 2014-09-03 12:25 ` Johannes Berg 2014-09-03 12:32 ` Henning Rogge 0 siblings, 1 reply; 10+ messages in thread From: Johannes Berg @ 2014-09-03 12:25 UTC (permalink / raw) To: Henning Rogge; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Wed, 2014-09-03 at 14:12 +0200, Henning Rogge wrote: > On Wed, Sep 3, 2014 at 1:52 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > > On Mon, 2014-09-01 at 13:26 +0200, Henning Rogge wrote: > >> The following patch adds NL80211_CMD_GET_MPP as a new nl80211 command that > >> allows to query the content of the 'mesh proxy path' table of mac80211s via > >> 'get' or 'dump' operation. > > > > For review and merging, and to make it more obvious to you as well when > > writing commit logs/documentation/etc I'd prefer if you'd split this up > > into separate cfg80211 and mac80211 patches. > > Just to make sure I got the split right... > > First patch to define the two new cfg80211_ops and the necessary > nl80211/tracing helper functions, second patch that implements > get_mpp() and dump_mpp() functions? Right. That way you have one patch that defines the API etc., and another that implements it, and it's easier to review and document the APIs in the right places etc. I don't always insist on this, but it's a pretty big patch so I'd prefer it this way (and it also should be almost trivial to split) > >> + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, > >> + u8 *dst, u8 *mpp, struct mpath_info *pinfo); > >> + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, > >> + int idx, u8 *dst, u8 *mpp, > >> + struct mpath_info *pinfo); > > > > Should dst/mpp be const? Or are those output parameters? > > Yes, similar to the get_mpath/dump_mpath cfg80211_ops these are output > parameters. Same thing for pinfo. Yeah I figured pinfo was, wasn't sure about the others :) > > Should it really be mpath_info? I thought this was some other thing? > > Probably just need more documentation :) > > mpath and mpp use the same storage object (struct mesh_path), so I > reused the mpath_info struct. As far as I can see its just a "transfer > object" between for cfg80211 that temporarily stores data from the > cfg80211_ops for nl80211 messages. Indeed, it is. > Shall I create a new struct for the two new cfg80211_ops? No need, I just wasn't sure it really needed the same data so figured I'd ask. > See I guess you got cut off there :) johannes ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-03 12:25 ` Johannes Berg @ 2014-09-03 12:32 ` Henning Rogge 2014-09-03 12:34 ` Johannes Berg 0 siblings, 1 reply; 10+ messages in thread From: Henning Rogge @ 2014-09-03 12:32 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Wed, Sep 3, 2014 at 2:25 PM, Johannes Berg <johannes@sipsolutions.net> wrote: >> First patch to define the two new cfg80211_ops and the necessary >> nl80211/tracing helper functions, second patch that implements >> get_mpp() and dump_mpp() functions? > > Right. That way you have one patch that defines the API etc., and > another that implements it, and it's easier to review and document the > APIs in the right places etc. > > I don't always insist on this, but it's a pretty big patch so I'd prefer > it this way (and it also should be almost trivial to split) Yes, should be easy. I will come back to the list with a "v2" set of patches. >> mpath and mpp use the same storage object (struct mesh_path), so I >> reused the mpath_info struct. As far as I can see its just a "transfer >> object" between for cfg80211 that temporarily stores data from the >> cfg80211_ops for nl80211 messages. > > Indeed, it is. > >> Shall I create a new struct for the two new cfg80211_ops? > > No need, I just wasn't sure it really needed the same data so figured > I'd ask. At the moment I don't use much of the mpath_info field... but I think the mpp operations will always use a subset of the mpath fields, so we can reuse the nl80211 encoding function by reusing the struct. If this changes it would be trivial to switch to a different struct, because its not visible from userspace. Henning ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch]mac80211: Add support for mesh proxy path dump 2014-09-03 12:32 ` Henning Rogge @ 2014-09-03 12:34 ` Johannes Berg 0 siblings, 0 replies; 10+ messages in thread From: Johannes Berg @ 2014-09-03 12:34 UTC (permalink / raw) To: Henning Rogge; +Cc: linux-wireless@vger.kernel.org, Yeoh Chun-Yeow On Wed, 2014-09-03 at 14:32 +0200, Henning Rogge wrote: > > No need, I just wasn't sure it really needed the same data so figured > > I'd ask. > > At the moment I don't use much of the mpath_info field... but I think > the mpp operations will always use a subset of the mpath fields, so we > can reuse the nl80211 encoding function by reusing the struct. If this > changes it would be trivial to switch to a different struct, because > its not visible from userspace. Makes sense I guess. Thanks for the explanation. johannes ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-09-03 12:34 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-09-01 11:26 [Patch]mac80211: Add support for mesh proxy path dump Henning Rogge 2014-09-01 12:03 ` Henning Rogge 2014-09-02 6:29 ` Yeoh Chun-Yeow 2014-09-02 8:03 ` Johannes Berg 2014-09-02 8:15 ` Henning Rogge 2014-09-03 11:52 ` Johannes Berg 2014-09-03 12:12 ` Henning Rogge 2014-09-03 12:25 ` Johannes Berg 2014-09-03 12:32 ` Henning Rogge 2014-09-03 12:34 ` Johannes Berg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).