aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-14 11:14:00 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-08 09:28:00 -0500
commitcf5ead822d5db2d276616ccca91f00eb3b855db2 (patch)
tree87568dbd398d139376a8fce358f4c176d31ad5ca /net/wireless/nl80211.c
parent052536abfa9144566599a7fbe8cc89e1086fa9a7 (diff)
cfg80211: allow including station info in delete event
When a station is removed, its statistics may be interesting to userspace, for example for further aggregation of statistics of all stations that ever connected to an AP. Introduce a new cfg80211_del_sta_sinfo() function (and make the cfg80211_del_sta() a static inline calling it) to allow passing a struct station_info along with this, and send the data in the nl80211 event message. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f56309bd21bd..a75dc91976d3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3650,8 +3650,8 @@ static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
3650 return true; 3650 return true;
3651} 3651}
3652 3652
3653static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 3653static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3654 int flags, 3654 u32 seq, int flags,
3655 struct cfg80211_registered_device *rdev, 3655 struct cfg80211_registered_device *rdev,
3656 struct net_device *dev, 3656 struct net_device *dev,
3657 const u8 *mac_addr, struct station_info *sinfo) 3657 const u8 *mac_addr, struct station_info *sinfo)
@@ -3659,7 +3659,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3659 void *hdr; 3659 void *hdr;
3660 struct nlattr *sinfoattr, *bss_param; 3660 struct nlattr *sinfoattr, *bss_param;
3661 3661
3662 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); 3662 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3663 if (!hdr) 3663 if (!hdr)
3664 return -1; 3664 return -1;
3665 3665
@@ -3854,7 +3854,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
3854 if (err) 3854 if (err)
3855 goto out_err; 3855 goto out_err;
3856 3856
3857 if (nl80211_send_station(skb, 3857 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
3858 NETLINK_CB(cb->skb).portid, 3858 NETLINK_CB(cb->skb).portid,
3859 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3859 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3860 rdev, wdev->netdev, mac_addr, 3860 rdev, wdev->netdev, mac_addr,
@@ -3901,7 +3901,8 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
3901 if (!msg) 3901 if (!msg)
3902 return -ENOMEM; 3902 return -ENOMEM;
3903 3903
3904 if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, 3904 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
3905 info->snd_portid, info->snd_seq, 0,
3905 rdev, dev, mac_addr, &sinfo) < 0) { 3906 rdev, dev, mac_addr, &sinfo) < 0) {
3906 nlmsg_free(msg); 3907 nlmsg_free(msg);
3907 return -ENOBUFS; 3908 return -ENOBUFS;
@@ -11687,7 +11688,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
11687 if (!msg) 11688 if (!msg)
11688 return; 11689 return;
11689 11690
11690 if (nl80211_send_station(msg, 0, 0, 0, 11691 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
11691 rdev, dev, mac_addr, sinfo) < 0) { 11692 rdev, dev, mac_addr, sinfo) < 0) {
11692 nlmsg_free(msg); 11693 nlmsg_free(msg);
11693 return; 11694 return;
@@ -11698,12 +11699,16 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
11698} 11699}
11699EXPORT_SYMBOL(cfg80211_new_sta); 11700EXPORT_SYMBOL(cfg80211_new_sta);
11700 11701
11701void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) 11702void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
11703 struct station_info *sinfo, gfp_t gfp)
11702{ 11704{
11703 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 11705 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
11704 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 11706 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11705 struct sk_buff *msg; 11707 struct sk_buff *msg;
11706 void *hdr; 11708 struct station_info empty_sinfo = {};
11709
11710 if (!sinfo)
11711 sinfo = &empty_sinfo;
11707 11712
11708 trace_cfg80211_del_sta(dev, mac_addr); 11713 trace_cfg80211_del_sta(dev, mac_addr);
11709 11714
@@ -11711,27 +11716,16 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
11711 if (!msg) 11716 if (!msg)
11712 return; 11717 return;
11713 11718
11714 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); 11719 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
11715 if (!hdr) { 11720 rdev, dev, mac_addr, sinfo)) {
11716 nlmsg_free(msg); 11721 nlmsg_free(msg);
11717 return; 11722 return;
11718 } 11723 }
11719 11724
11720 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
11721 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
11722 goto nla_put_failure;
11723
11724 genlmsg_end(msg, hdr);
11725
11726 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 11725 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11727 NL80211_MCGRP_MLME, gfp); 11726 NL80211_MCGRP_MLME, gfp);
11728 return;
11729
11730 nla_put_failure:
11731 genlmsg_cancel(msg, hdr);
11732 nlmsg_free(msg);
11733} 11727}
11734EXPORT_SYMBOL(cfg80211_del_sta); 11728EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
11735 11729
11736void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, 11730void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
11737 enum nl80211_connect_failed_reason reason, 11731 enum nl80211_connect_failed_reason reason,