diff options
| author | Henning Rogge <hrogge@gmail.com> | 2014-09-12 02:58:49 -0400 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2014-10-09 05:19:07 -0400 |
| commit | 66be7d2bcd826344894be09dc385f9f805136b84 (patch) | |
| tree | 9f9acb5aae9025d59db6520412f4d26044436a4d | |
| parent | cc61d8df0a0157fabae2a3422f0b7f9f18f81c82 (diff) | |
cfg80211: add ops to query mesh proxy path table
Add two new cfg80211 operations for querying a table with proxied mesh
paths.
Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
| -rw-r--r-- | include/net/cfg80211.h | 7 | ||||
| -rw-r--r-- | include/uapi/linux/nl80211.h | 6 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 99 | ||||
| -rw-r--r-- | net/wireless/rdev-ops.h | 27 | ||||
| -rw-r--r-- | net/wireless/trace.h | 45 |
5 files changed, 183 insertions, 1 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a2ddcf2398fd..3f3aaa06adb5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -2146,6 +2146,8 @@ struct cfg80211_qos_map { | |||
| 2146 | * @change_mpath: change a given mesh path | 2146 | * @change_mpath: change a given mesh path |
| 2147 | * @get_mpath: get a mesh path for the given parameters | 2147 | * @get_mpath: get a mesh path for the given parameters |
| 2148 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx | 2148 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx |
| 2149 | * @get_mpp: get a mesh proxy path for the given parameters | ||
| 2150 | * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx | ||
| 2149 | * @join_mesh: join the mesh network with the specified parameters | 2151 | * @join_mesh: join the mesh network with the specified parameters |
| 2150 | * (invoked with the wireless_dev mutex held) | 2152 | * (invoked with the wireless_dev mutex held) |
| 2151 | * @leave_mesh: leave the current mesh network | 2153 | * @leave_mesh: leave the current mesh network |
| @@ -2396,6 +2398,11 @@ struct cfg80211_ops { | |||
| 2396 | int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, | 2398 | int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, |
| 2397 | int idx, u8 *dst, u8 *next_hop, | 2399 | int idx, u8 *dst, u8 *next_hop, |
| 2398 | struct mpath_info *pinfo); | 2400 | struct mpath_info *pinfo); |
| 2401 | int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, | ||
| 2402 | u8 *dst, u8 *mpp, struct mpath_info *pinfo); | ||
| 2403 | int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, | ||
| 2404 | int idx, u8 *dst, u8 *mpp, | ||
| 2405 | struct mpath_info *pinfo); | ||
| 2399 | int (*get_mesh_config)(struct wiphy *wiphy, | 2406 | int (*get_mesh_config)(struct wiphy *wiphy, |
| 2400 | struct net_device *dev, | 2407 | struct net_device *dev, |
| 2401 | struct mesh_config *conf); | 2408 | struct mesh_config *conf); |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 4b28dc07bcb1..846071b0cde9 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
| @@ -738,6 +738,10 @@ | |||
| 738 | * before removing a station entry entirely, or before disassociating | 738 | * before removing a station entry entirely, or before disassociating |
| 739 | * or similar, cleanup will happen in the driver/device in this case. | 739 | * or similar, cleanup will happen in the driver/device in this case. |
| 740 | * | 740 | * |
| 741 | * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to | ||
| 742 | * destination %NL80211_ATTR_MAC on the interface identified by | ||
| 743 | * %NL80211_ATTR_IFINDEX. | ||
| 744 | * | ||
| 741 | * @NL80211_CMD_MAX: highest used command number | 745 | * @NL80211_CMD_MAX: highest used command number |
| 742 | * @__NL80211_CMD_AFTER_LAST: internal use | 746 | * @__NL80211_CMD_AFTER_LAST: internal use |
| 743 | */ | 747 | */ |
| @@ -912,6 +916,8 @@ enum nl80211_commands { | |||
| 912 | NL80211_CMD_ADD_TX_TS, | 916 | NL80211_CMD_ADD_TX_TS, |
| 913 | NL80211_CMD_DEL_TX_TS, | 917 | NL80211_CMD_DEL_TX_TS, |
| 914 | 918 | ||
| 919 | NL80211_CMD_GET_MPP, | ||
| 920 | |||
| 915 | /* add new commands above here */ | 921 | /* add new commands above here */ |
| 916 | 922 | ||
| 917 | /* used to define NL80211_CMD_MAX below */ | 923 | /* used to define NL80211_CMD_MAX below */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cb9f5a44ffad..d527aa0706c1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -4624,6 +4624,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | |||
| 4624 | return rdev_del_mpath(rdev, dev, dst); | 4624 | return rdev_del_mpath(rdev, dev, dst); |
| 4625 | } | 4625 | } |
| 4626 | 4626 | ||
| 4627 | static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) | ||
| 4628 | { | ||
| 4629 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
| 4630 | int err; | ||
| 4631 | struct net_device *dev = info->user_ptr[1]; | ||
| 4632 | struct mpath_info pinfo; | ||
| 4633 | struct sk_buff *msg; | ||
| 4634 | u8 *dst = NULL; | ||
| 4635 | u8 mpp[ETH_ALEN]; | ||
| 4636 | |||
| 4637 | memset(&pinfo, 0, sizeof(pinfo)); | ||
| 4638 | |||
| 4639 | if (!info->attrs[NL80211_ATTR_MAC]) | ||
| 4640 | return -EINVAL; | ||
| 4641 | |||
| 4642 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
| 4643 | |||
| 4644 | if (!rdev->ops->get_mpp) | ||
| 4645 | return -EOPNOTSUPP; | ||
| 4646 | |||
| 4647 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | ||
| 4648 | return -EOPNOTSUPP; | ||
| 4649 | |||
| 4650 | err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); | ||
| 4651 | if (err) | ||
| 4652 | return err; | ||
| 4653 | |||
| 4654 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
| 4655 | if (!msg) | ||
| 4656 | return -ENOMEM; | ||
| 4657 | |||
| 4658 | if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, | ||
| 4659 | dev, dst, mpp, &pinfo) < 0) { | ||
| 4660 | nlmsg_free(msg); | ||
| 4661 | return -ENOBUFS; | ||
| 4662 | } | ||
| 4663 | |||
| 4664 | return genlmsg_reply(msg, info); | ||
| 4665 | } | ||
| 4666 | |||
| 4667 | static int nl80211_dump_mpp(struct sk_buff *skb, | ||
| 4668 | struct netlink_callback *cb) | ||
| 4669 | { | ||
| 4670 | struct mpath_info pinfo; | ||
| 4671 | struct cfg80211_registered_device *rdev; | ||
| 4672 | struct wireless_dev *wdev; | ||
| 4673 | u8 dst[ETH_ALEN]; | ||
| 4674 | u8 mpp[ETH_ALEN]; | ||
| 4675 | int path_idx = cb->args[2]; | ||
| 4676 | int err; | ||
| 4677 | |||
| 4678 | err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); | ||
| 4679 | if (err) | ||
| 4680 | return err; | ||
| 4681 | |||
| 4682 | if (!rdev->ops->dump_mpp) { | ||
| 4683 | err = -EOPNOTSUPP; | ||
| 4684 | goto out_err; | ||
| 4685 | } | ||
| 4686 | |||
| 4687 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
| 4688 | err = -EOPNOTSUPP; | ||
| 4689 | goto out_err; | ||
| 4690 | } | ||
| 4691 | |||
| 4692 | while (1) { | ||
| 4693 | err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, | ||
| 4694 | mpp, &pinfo); | ||
| 4695 | if (err == -ENOENT) | ||
| 4696 | break; | ||
| 4697 | if (err) | ||
| 4698 | goto out_err; | ||
| 4699 | |||
| 4700 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, | ||
| 4701 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
| 4702 | wdev->netdev, dst, mpp, | ||
| 4703 | &pinfo) < 0) | ||
| 4704 | goto out; | ||
| 4705 | |||
| 4706 | path_idx++; | ||
| 4707 | } | ||
| 4708 | |||
| 4709 | out: | ||
| 4710 | cb->args[2] = path_idx; | ||
| 4711 | err = skb->len; | ||
| 4712 | out_err: | ||
| 4713 | nl80211_finish_wdev_dump(rdev); | ||
| 4714 | return err; | ||
| 4715 | } | ||
| 4716 | |||
| 4627 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | 4717 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) |
| 4628 | { | 4718 | { |
| 4629 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4719 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| @@ -9774,6 +9864,15 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 9774 | NL80211_FLAG_NEED_RTNL, | 9864 | NL80211_FLAG_NEED_RTNL, |
| 9775 | }, | 9865 | }, |
| 9776 | { | 9866 | { |
| 9867 | .cmd = NL80211_CMD_GET_MPP, | ||
| 9868 | .doit = nl80211_get_mpp, | ||
| 9869 | .dumpit = nl80211_dump_mpp, | ||
| 9870 | .policy = nl80211_policy, | ||
| 9871 | .flags = GENL_ADMIN_PERM, | ||
| 9872 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
| 9873 | NL80211_FLAG_NEED_RTNL, | ||
| 9874 | }, | ||
| 9875 | { | ||
| 9777 | .cmd = NL80211_CMD_SET_MPATH, | 9876 | .cmd = NL80211_CMD_SET_MPATH, |
| 9778 | .doit = nl80211_set_mpath, | 9877 | .doit = nl80211_set_mpath, |
| 9779 | .policy = nl80211_policy, | 9878 | .policy = nl80211_policy, |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index f6d457d6a558..c09e697bcb15 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, | |||
| 263 | 263 | ||
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, | ||
| 267 | struct net_device *dev, u8 *dst, u8 *mpp, | ||
| 268 | struct mpath_info *pinfo) | ||
| 269 | { | ||
| 270 | int ret; | ||
| 271 | |||
| 272 | trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); | ||
| 273 | ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); | ||
| 274 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
| 275 | return ret; | ||
| 276 | } | ||
| 277 | |||
| 266 | static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, | 278 | static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, |
| 267 | struct net_device *dev, int idx, u8 *dst, | 279 | struct net_device *dev, int idx, u8 *dst, |
| 268 | u8 *next_hop, struct mpath_info *pinfo) | 280 | u8 *next_hop, struct mpath_info *pinfo) |
| @@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, | |||
| 271 | int ret; | 283 | int ret; |
| 272 | trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); | 284 | trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); |
| 273 | ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, | 285 | ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, |
| 274 | pinfo); | 286 | pinfo); |
| 287 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
| 288 | return ret; | ||
| 289 | } | ||
| 290 | |||
| 291 | static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, | ||
| 292 | struct net_device *dev, int idx, u8 *dst, | ||
| 293 | u8 *mpp, struct mpath_info *pinfo) | ||
| 294 | |||
| 295 | { | ||
| 296 | int ret; | ||
| 297 | |||
| 298 | trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); | ||
| 299 | ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); | ||
| 275 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | 300 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); |
| 276 | return ret; | 301 | return ret; |
| 277 | } | 302 | } |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 625a6e6d1168..8e4f8f04332d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
| @@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath, | |||
| 801 | MAC_PR_ARG(next_hop)) | 801 | MAC_PR_ARG(next_hop)) |
| 802 | ); | 802 | ); |
| 803 | 803 | ||
| 804 | TRACE_EVENT(rdev_get_mpp, | ||
| 805 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
| 806 | u8 *dst, u8 *mpp), | ||
| 807 | TP_ARGS(wiphy, netdev, dst, mpp), | ||
| 808 | TP_STRUCT__entry( | ||
| 809 | WIPHY_ENTRY | ||
| 810 | NETDEV_ENTRY | ||
| 811 | MAC_ENTRY(dst) | ||
| 812 | MAC_ENTRY(mpp) | ||
| 813 | ), | ||
| 814 | TP_fast_assign( | ||
| 815 | WIPHY_ASSIGN; | ||
| 816 | NETDEV_ASSIGN; | ||
| 817 | MAC_ASSIGN(dst, dst); | ||
| 818 | MAC_ASSIGN(mpp, mpp); | ||
| 819 | ), | ||
| 820 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT | ||
| 821 | ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, | ||
| 822 | MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) | ||
| 823 | ); | ||
| 824 | |||
| 825 | TRACE_EVENT(rdev_dump_mpp, | ||
| 826 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, | ||
| 827 | u8 *dst, u8 *mpp), | ||
| 828 | TP_ARGS(wiphy, netdev, idx, mpp, dst), | ||
| 829 | TP_STRUCT__entry( | ||
| 830 | WIPHY_ENTRY | ||
| 831 | NETDEV_ENTRY | ||
| 832 | MAC_ENTRY(dst) | ||
| 833 | MAC_ENTRY(mpp) | ||
| 834 | __field(int, idx) | ||
| 835 | ), | ||
| 836 | TP_fast_assign( | ||
| 837 | WIPHY_ASSIGN; | ||
| 838 | NETDEV_ASSIGN; | ||
| 839 | MAC_ASSIGN(dst, dst); | ||
| 840 | MAC_ASSIGN(mpp, mpp); | ||
| 841 | __entry->idx = idx; | ||
| 842 | ), | ||
| 843 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " | ||
| 844 | MAC_PR_FMT ", mpp: " MAC_PR_FMT, | ||
| 845 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), | ||
| 846 | MAC_PR_ARG(mpp)) | ||
| 847 | ); | ||
| 848 | |||
| 804 | TRACE_EVENT(rdev_return_int_mpath_info, | 849 | TRACE_EVENT(rdev_return_int_mpath_info, |
| 805 | TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), | 850 | TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), |
| 806 | TP_ARGS(wiphy, ret, pinfo), | 851 | TP_ARGS(wiphy, ret, pinfo), |
