mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
fix up hostapd for mac80211
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@9554 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
208
package/mac80211/patches/024-nl80211-get-sta.patch
Normal file
208
package/mac80211/patches/024-nl80211-get-sta.patch
Normal file
@@ -0,0 +1,208 @@
|
||||
Subject: cfg80211/nl80211: implement station attribute retrieval
|
||||
|
||||
After a station is added to the kernel's structures, userspace
|
||||
has to be able to retrieve statistics about that station, especially
|
||||
whether the station was idle and how much bytes were transferred
|
||||
to and from it. This adds the necessary code to nl80211.
|
||||
|
||||
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
|
||||
|
||||
---
|
||||
include/linux/nl80211.h | 28 ++++++++++++++++
|
||||
include/net/cfg80211.h | 35 ++++++++++++++++++++
|
||||
net/wireless/nl80211.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 144 insertions(+), 1 deletion(-)
|
||||
|
||||
--- everything.orig/include/linux/nl80211.h 2007-11-08 17:15:15.961529840 +0100
|
||||
+++ everything/include/linux/nl80211.h 2007-11-08 17:17:00.891547364 +0100
|
||||
@@ -157,6 +157,9 @@ enum nl80211_commands {
|
||||
* restriction (at most %NL80211_MAX_SUPP_RATES).
|
||||
* @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
|
||||
* to, or the AP interface the station was originally added to to.
|
||||
+ * @NL80211_ATTR_STA_STATS: statistics for a station, part of station info
|
||||
+ * given for %NL80211_CMD_GET_STATION, nested attribute containing
|
||||
+ * info as possible, see &enum nl80211_sta_stats.
|
||||
*
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -190,6 +193,7 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_STA_LISTEN_INTERVAL,
|
||||
NL80211_ATTR_STA_SUPPORTED_RATES,
|
||||
NL80211_ATTR_STA_VLAN,
|
||||
+ NL80211_ATTR_STA_STATS,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
@@ -252,4 +256,28 @@ enum nl80211_sta_flags {
|
||||
NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * enum nl80211_sta_stats - station statistics
|
||||
+ *
|
||||
+ * These attribute types are used with %NL80211_ATTR_STA_STATS
|
||||
+ * when getting information about a station.
|
||||
+ *
|
||||
+ * @__NL80211_STA_STAT_INVALID: attribute number 0 is reserved
|
||||
+ * @NL80211_STA_STAT_INACTIVE_TIME: time since last activity (u32, msecs)
|
||||
+ * @NL80211_STA_STAT_RX_BYTES: total received bytes (u32, from this station)
|
||||
+ * @NL80211_STA_STAT_TX_BYTES: total transmitted bytes (u32, to this station)
|
||||
+ * @__NL80211_STA_STAT_AFTER_LAST: internal
|
||||
+ * @NL80211_STA_STAT_MAX: highest possible station stats attribute
|
||||
+ */
|
||||
+enum nl80211_sta_stats {
|
||||
+ __NL80211_STA_STAT_INVALID,
|
||||
+ NL80211_STA_STAT_INACTIVE_TIME,
|
||||
+ NL80211_STA_STAT_RX_BYTES,
|
||||
+ NL80211_STA_STAT_TX_BYTES,
|
||||
+
|
||||
+ /* keep last */
|
||||
+ __NL80211_STA_STAT_AFTER_LAST,
|
||||
+ NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1
|
||||
+};
|
||||
+
|
||||
#endif /* __LINUX_NL80211_H */
|
||||
--- everything.orig/include/net/cfg80211.h 2007-11-08 17:15:15.971532444 +0100
|
||||
+++ everything/include/net/cfg80211.h 2007-11-08 17:17:00.891547364 +0100
|
||||
@@ -130,6 +130,39 @@ struct station_parameters {
|
||||
u8 supported_rates_len;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * enum station_stats_flags - station statistics flags
|
||||
+ *
|
||||
+ * Used by the driver to indicate which info in &struct station_stats
|
||||
+ * it has filled in during get_station().
|
||||
+ *
|
||||
+ * @STATION_STAT_INACTIVE_TIME: @inactive_time filled
|
||||
+ * @STATION_STAT_RX_BYTES: @rx_bytes filled
|
||||
+ * @STATION_STAT_TX_BYTES: @tx_bytes filled
|
||||
+ */
|
||||
+enum station_stats_flags {
|
||||
+ STATION_STAT_INACTIVE_TIME = 1<<0,
|
||||
+ STATION_STAT_RX_BYTES = 1<<1,
|
||||
+ STATION_STAT_TX_BYTES = 1<<2,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct station_stats - station statistics
|
||||
+ *
|
||||
+ * Station information filled by driver for get_station().
|
||||
+ *
|
||||
+ * @filled: bitflag of flags from &enum station_stats_flags
|
||||
+ * @inactive_time: time since last station activity (tx/rx) in milliseconds
|
||||
+ * @rx_bytes: bytes received from this station
|
||||
+ * @tx_bytes: bytes transmitted to this station
|
||||
+ */
|
||||
+struct station_stats {
|
||||
+ u32 filled;
|
||||
+ u32 inactive_time;
|
||||
+ u32 rx_bytes;
|
||||
+ u32 tx_bytes;
|
||||
+};
|
||||
+
|
||||
/* from net/wireless.h */
|
||||
struct wiphy;
|
||||
|
||||
@@ -209,6 +242,8 @@ struct cfg80211_ops {
|
||||
u8 *mac);
|
||||
int (*change_station)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *mac, struct station_parameters *params);
|
||||
+ int (*get_station)(struct wiphy *wiphy, struct net_device *dev,
|
||||
+ u8 *mac, struct station_stats *stats);
|
||||
};
|
||||
|
||||
#endif /* __NET_CFG80211_H */
|
||||
--- everything.orig/net/wireless/nl80211.c 2007-11-08 17:15:15.981533909 +0100
|
||||
+++ everything/net/wireless/nl80211.c 2007-11-08 17:17:00.901534235 +0100
|
||||
@@ -751,9 +751,89 @@ static int parse_station_flags(struct nl
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
|
||||
+ int flags, struct net_device *dev,
|
||||
+ u8 *mac_addr, struct station_stats *stats)
|
||||
+{
|
||||
+ void *hdr;
|
||||
+ struct nlattr *statsattr;
|
||||
+
|
||||
+ hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
|
||||
+ if (!hdr)
|
||||
+ return -1;
|
||||
+
|
||||
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
|
||||
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
|
||||
+
|
||||
+ statsattr = nla_nest_start(msg, NL80211_ATTR_STA_STATS);
|
||||
+ if (!statsattr)
|
||||
+ goto nla_put_failure;
|
||||
+ if (stats->filled & STATION_STAT_INACTIVE_TIME)
|
||||
+ NLA_PUT_U32(msg, NL80211_STA_STAT_INACTIVE_TIME,
|
||||
+ stats->inactive_time);
|
||||
+ if (stats->filled & STATION_STAT_RX_BYTES)
|
||||
+ NLA_PUT_U32(msg, NL80211_STA_STAT_RX_BYTES,
|
||||
+ stats->rx_bytes);
|
||||
+ if (stats->filled & STATION_STAT_TX_BYTES)
|
||||
+ NLA_PUT_U32(msg, NL80211_STA_STAT_TX_BYTES,
|
||||
+ stats->tx_bytes);
|
||||
+
|
||||
+ nla_nest_end(msg, statsattr);
|
||||
+
|
||||
+ return genlmsg_end(msg, hdr);
|
||||
+
|
||||
+ nla_put_failure:
|
||||
+ return genlmsg_cancel(msg, hdr);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
- return -EOPNOTSUPP;
|
||||
+ struct cfg80211_registered_device *drv;
|
||||
+ int err;
|
||||
+ struct net_device *dev;
|
||||
+ struct station_stats stats;
|
||||
+ struct sk_buff *msg;
|
||||
+ u8 *mac_addr = NULL;
|
||||
+
|
||||
+ memset(&stats, 0, sizeof(stats));
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_MAC])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
+
|
||||
+ err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (!drv->ops->get_station) {
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ rtnl_lock();
|
||||
+ err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &stats);
|
||||
+ rtnl_unlock();
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
+ if (!msg)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
|
||||
+ dev, mac_addr, &stats) < 0)
|
||||
+ goto out_free;
|
||||
+
|
||||
+ err = genlmsg_unicast(msg, info->snd_pid);
|
||||
+ goto out;
|
||||
+
|
||||
+ out_free:
|
||||
+ nlmsg_free(msg);
|
||||
+
|
||||
+ out:
|
||||
+ cfg80211_put_dev(drv);
|
||||
+ dev_put(dev);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/*
|
||||
Reference in New Issue
Block a user