diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 94ab2014fefe..9555ef9fd99e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6613,12 +6613,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) | |||
6613 | } | 6613 | } |
6614 | 6614 | ||
6615 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | 6615 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, |
6616 | int flags, struct net_device *dev, | 6616 | int flags, struct net_device *dev, |
6617 | struct survey_info *survey) | 6617 | bool allow_radio_stats, |
6618 | struct survey_info *survey) | ||
6618 | { | 6619 | { |
6619 | void *hdr; | 6620 | void *hdr; |
6620 | struct nlattr *infoattr; | 6621 | struct nlattr *infoattr; |
6621 | 6622 | ||
6623 | /* skip radio stats if userspace didn't request them */ | ||
6624 | if (!survey->channel && !allow_radio_stats) | ||
6625 | return 0; | ||
6626 | |||
6622 | hdr = nl80211hdr_put(msg, portid, seq, flags, | 6627 | hdr = nl80211hdr_put(msg, portid, seq, flags, |
6623 | NL80211_CMD_NEW_SURVEY_RESULTS); | 6628 | NL80211_CMD_NEW_SURVEY_RESULTS); |
6624 | if (!hdr) | 6629 | if (!hdr) |
@@ -6631,7 +6636,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | |||
6631 | if (!infoattr) | 6636 | if (!infoattr) |
6632 | goto nla_put_failure; | 6637 | goto nla_put_failure; |
6633 | 6638 | ||
6634 | if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, | 6639 | if (survey->channel && |
6640 | nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, | ||
6635 | survey->channel->center_freq)) | 6641 | survey->channel->center_freq)) |
6636 | goto nla_put_failure; | 6642 | goto nla_put_failure; |
6637 | 6643 | ||
@@ -6671,19 +6677,22 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | |||
6671 | return -EMSGSIZE; | 6677 | return -EMSGSIZE; |
6672 | } | 6678 | } |
6673 | 6679 | ||
6674 | static int nl80211_dump_survey(struct sk_buff *skb, | 6680 | static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) |
6675 | struct netlink_callback *cb) | ||
6676 | { | 6681 | { |
6677 | struct survey_info survey; | 6682 | struct survey_info survey; |
6678 | struct cfg80211_registered_device *rdev; | 6683 | struct cfg80211_registered_device *rdev; |
6679 | struct wireless_dev *wdev; | 6684 | struct wireless_dev *wdev; |
6680 | int survey_idx = cb->args[2]; | 6685 | int survey_idx = cb->args[2]; |
6681 | int res; | 6686 | int res; |
6687 | bool radio_stats; | ||
6682 | 6688 | ||
6683 | res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); | 6689 | res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
6684 | if (res) | 6690 | if (res) |
6685 | return res; | 6691 | return res; |
6686 | 6692 | ||
6693 | /* prepare_wdev_dump parsed the attributes */ | ||
6694 | radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; | ||
6695 | |||
6687 | if (!wdev->netdev) { | 6696 | if (!wdev->netdev) { |
6688 | res = -EINVAL; | 6697 | res = -EINVAL; |
6689 | goto out_err; | 6698 | goto out_err; |
@@ -6701,13 +6710,9 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6701 | if (res) | 6710 | if (res) |
6702 | goto out_err; | 6711 | goto out_err; |
6703 | 6712 | ||
6704 | /* Survey without a channel doesn't make sense */ | 6713 | /* don't send disabled channels, but do send non-channel data */ |
6705 | if (!survey.channel) { | 6714 | if (survey.channel && |
6706 | res = -EINVAL; | 6715 | survey.channel->flags & IEEE80211_CHAN_DISABLED) { |
6707 | goto out; | ||
6708 | } | ||
6709 | |||
6710 | if (survey.channel->flags & IEEE80211_CHAN_DISABLED) { | ||
6711 | survey_idx++; | 6716 | survey_idx++; |
6712 | continue; | 6717 | continue; |
6713 | } | 6718 | } |
@@ -6715,7 +6720,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6715 | if (nl80211_send_survey(skb, | 6720 | if (nl80211_send_survey(skb, |
6716 | NETLINK_CB(cb->skb).portid, | 6721 | NETLINK_CB(cb->skb).portid, |
6717 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 6722 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
6718 | wdev->netdev, &survey) < 0) | 6723 | wdev->netdev, radio_stats, &survey) < 0) |
6719 | goto out; | 6724 | goto out; |
6720 | survey_idx++; | 6725 | survey_idx++; |
6721 | } | 6726 | } |