* [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; +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; +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, 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, 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, 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, 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, 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, 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, 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, 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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.