Commit b7fb44da authored by Denis Kenzior's avatar Denis Kenzior Committed by Johannes Berg

nl80211: Allow GET_INTERFACE dumps to be filtered

This patch allows GET_INTERFACE dumps to be filtered based on
NL80211_ATTR_WIPHY or NL80211_ATTR_WDEV.  The documentation for
GET_INTERFACE mentions that this is possible:
"Request an interface's configuration; either a dump request on
a %NL80211_ATTR_WIPHY or ..."

However, this behavior has not been implemented until now.

Johannes: rewrite most of the patch:
 * use nl80211_dump_wiphy_parse() to also allow passing an interface
   to be able to dump its siblings
 * fix locking (must hold rtnl around using nl80211_fam.attrbuf)
 * make init self-contained instead of relying on other cb->args
Signed-off-by: default avatarDenis Kenzior <denkenz@gmail.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 02154927
...@@ -2525,10 +2525,35 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * ...@@ -2525,10 +2525,35 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
int if_idx = 0; int if_idx = 0;
int wp_start = cb->args[0]; int wp_start = cb->args[0];
int if_start = cb->args[1]; int if_start = cb->args[1];
int filter_wiphy = -1;
struct cfg80211_registered_device *rdev; struct cfg80211_registered_device *rdev;
struct wireless_dev *wdev; struct wireless_dev *wdev;
rtnl_lock(); rtnl_lock();
if (!cb->args[2]) {
struct nl80211_dump_wiphy_state state = {
.filter_wiphy = -1,
};
int ret;
ret = nl80211_dump_wiphy_parse(skb, cb, &state);
if (ret)
return ret;
filter_wiphy = state.filter_wiphy;
/*
* if filtering, set cb->args[2] to +1 since 0 is the default
* value needed to determine that parsing is necessary.
*/
if (filter_wiphy >= 0)
cb->args[2] = filter_wiphy + 1;
else
cb->args[2] = -1;
} else if (cb->args[2] > 0) {
filter_wiphy = cb->args[2] - 1;
}
list_for_each_entry(rdev, &cfg80211_rdev_list, list) { list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
continue; continue;
...@@ -2536,6 +2561,10 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * ...@@ -2536,6 +2561,10 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
wp_idx++; wp_idx++;
continue; continue;
} }
if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
continue;
if_idx = 0; if_idx = 0;
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment