From 67dd9a73dcb62e5b072244dddd7b19d521e20e67 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 16 Nov 2007 03:10:56 +0000 Subject: fix up hostapd for mac80211 SVN-Revision: 9554 --- package/mac80211/patches/022-nl80211-sta.patch | 464 +++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 package/mac80211/patches/022-nl80211-sta.patch (limited to 'package/mac80211/patches/022-nl80211-sta.patch') diff --git a/package/mac80211/patches/022-nl80211-sta.patch b/package/mac80211/patches/022-nl80211-sta.patch new file mode 100644 index 0000000000..4d08721f82 --- /dev/null +++ b/package/mac80211/patches/022-nl80211-sta.patch @@ -0,0 +1,464 @@ +Subject: cfg80211/nl80211: station handling + +This patch adds station handling to cfg80211/nl80211. + +Signed-off-by: Johannes Berg + +--- + include/linux/nl80211.h | 68 +++++++++++++ + include/net/cfg80211.h | 54 ++++++++++ + net/wireless/nl80211.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 358 insertions(+) + +--- everything.orig/include/linux/nl80211.h 2007-11-08 16:56:32.431522732 +0100 ++++ everything/include/linux/nl80211.h 2007-11-08 17:15:15.961529840 +0100 +@@ -7,6 +7,18 @@ + */ + + /** ++ * DOC: Station handling ++ * ++ * Stations are added per interface, but a special case exists with VLAN ++ * interfaces. When a station is bound to an AP interface, it may be moved ++ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). ++ * The station is still assumed to belong to the AP interface it was added ++ * to. ++ * ++ * TODO: need more info? ++ */ ++ ++/** + * enum nl80211_commands - supported nl80211 commands + * + * @NL80211_CMD_UNSPEC: unspecified command to catch errors +@@ -56,6 +68,16 @@ + * parameters are like for %NL80211_CMD_SET_BEACON. + * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it + * ++ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by ++ * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. ++ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by ++ * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. ++ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the ++ * the interface identified by %NL80211_ATTR_IFINDEX. ++ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC ++ * or, if no MAC address given, all stations, on the interface identified ++ * by %NL80211_ATTR_IFINDEX. ++ * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +@@ -83,6 +105,11 @@ enum nl80211_commands { + NL80211_CMD_NEW_BEACON, + NL80211_CMD_DEL_BEACON, + ++ NL80211_CMD_GET_STATION, ++ NL80211_CMD_SET_STATION, ++ NL80211_CMD_NEW_STATION, ++ NL80211_CMD_DEL_STATION, ++ + /* add commands here */ + + /* used to define NL80211_CMD_MAX below */ +@@ -120,6 +147,17 @@ enum nl80211_commands { + * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE + * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE + * ++ * @NL80211_ATTR_STA_AID: Association ID for the station (u16) ++ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of ++ * &enum nl80211_sta_flags. ++ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by ++ * IEEE 802.11 7.3.1.6 (u16). ++ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported ++ * rates as defined by IEEE 802.11 7.3.2.2 but without the length ++ * 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_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +@@ -147,12 +185,20 @@ enum nl80211_attrs { + NL80211_ATTR_BEACON_HEAD, + NL80211_ATTR_BEACON_TAIL, + ++ NL80211_ATTR_STA_AID, ++ NL80211_ATTR_STA_FLAGS, ++ NL80211_ATTR_STA_LISTEN_INTERVAL, ++ NL80211_ATTR_STA_SUPPORTED_RATES, ++ NL80211_ATTR_STA_VLAN, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, + NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 + }; + ++#define NL80211_MAX_SUPP_RATES 32 ++ + /** + * enum nl80211_iftype - (virtual) interface types + * +@@ -184,4 +230,26 @@ enum nl80211_iftype { + NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1 + }; + ++/** ++ * enum nl80211_sta_flags - station flags ++ * ++ * Station flags. When a station is added to an AP interface, it is ++ * assumed to be already associated (and hence authenticated.) ++ * ++ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) ++ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames ++ * with short barker preamble ++ * @NL80211_STA_FLAG_WME: station is WME/QoS capable ++ */ ++enum nl80211_sta_flags { ++ __NL80211_STA_FLAG_INVALID, ++ NL80211_STA_FLAG_AUTHORIZED, ++ NL80211_STA_FLAG_SHORT_PREAMBLE, ++ NL80211_STA_FLAG_WME, ++ ++ /* keep last */ ++ __NL80211_STA_FLAG_AFTER_LAST, ++ NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 ++}; ++ + #endif /* __LINUX_NL80211_H */ +--- everything.orig/include/net/cfg80211.h 2007-11-08 16:50:38.421522842 +0100 ++++ everything/include/net/cfg80211.h 2007-11-08 17:15:15.971532444 +0100 +@@ -89,6 +89,47 @@ struct beacon_parameters { + int head_len, tail_len; + }; + ++/** ++ * enum station_flags - station flags ++ * ++ * Station capability flags. Note that these must be the bits ++ * according to the nl80211 flags. ++ * ++ * @STATION_FLAG_CHANGED: station flags were changed ++ * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X) ++ * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames ++ * with short preambles ++ * @STATION_FLAG_WME: station is WME/QoS capable ++ */ ++enum station_flags { ++ STATION_FLAG_CHANGED = 1<<0, ++ STATION_FLAG_AUTHORIZED = 1<ieee80211_ptr) ++ return -EINVAL; ++ if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy) ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *drv; ++ int err; ++ struct net_device *dev; ++ struct station_parameters params; ++ u8 *mac_addr = NULL; ++ ++ memset(¶ms, 0, sizeof(params)); ++ ++ params.listen_interval = -1; ++ ++ if (info->attrs[NL80211_ATTR_STA_AID]) ++ return -EINVAL; ++ ++ if (!info->attrs[NL80211_ATTR_MAC]) ++ return -EINVAL; ++ ++ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); ++ ++ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) { ++ params.supported_rates = ++ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); ++ params.supported_rates_len = ++ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); ++ } ++ ++ if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) ++ params.listen_interval = ++ nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); ++ ++ if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], ++ ¶ms.station_flags)) ++ return -EINVAL; ++ ++ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); ++ if (err) ++ return err; ++ ++ err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); ++ if (err) ++ goto out; ++ ++ if (!drv->ops->change_station) { ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ rtnl_lock(); ++ err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms); ++ rtnl_unlock(); ++ ++ out: ++ if (params.vlan) ++ dev_put(params.vlan); ++ cfg80211_put_dev(drv); ++ dev_put(dev); ++ return err; ++} ++ ++static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *drv; ++ int err; ++ struct net_device *dev; ++ struct station_parameters params; ++ u8 *mac_addr = NULL; ++ ++ memset(¶ms, 0, sizeof(params)); ++ ++ if (!info->attrs[NL80211_ATTR_MAC]) ++ return -EINVAL; ++ ++ if (!info->attrs[NL80211_ATTR_STA_AID]) ++ return -EINVAL; ++ ++ if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) ++ return -EINVAL; ++ ++ if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) ++ return -EINVAL; ++ ++ mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); ++ params.supported_rates = ++ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); ++ params.supported_rates_len = ++ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); ++ params.listen_interval = ++ nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); ++ params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); ++ ++ if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], ++ ¶ms.station_flags)) ++ return -EINVAL; ++ ++ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); ++ if (err) ++ return err; ++ ++ err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); ++ if (err) ++ goto out; ++ ++ if (!drv->ops->add_station) { ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ rtnl_lock(); ++ err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms); ++ rtnl_unlock(); ++ ++ out: ++ if (params.vlan) ++ dev_put(params.vlan); ++ cfg80211_put_dev(drv); ++ dev_put(dev); ++ return err; ++} ++ ++static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *drv; ++ int err; ++ struct net_device *dev; ++ u8 *mac_addr = NULL; ++ ++ if (info->attrs[NL80211_ATTR_MAC]) ++ 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->del_station) { ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ rtnl_lock(); ++ err = drv->ops->del_station(&drv->wiphy, dev, mac_addr); ++ rtnl_unlock(); ++ ++ out: ++ cfg80211_put_dev(drv); ++ dev_put(dev); ++ return err; ++} ++ + static struct genl_ops nl80211_ops[] = { + { + .cmd = NL80211_CMD_GET_WIPHY, +@@ -796,6 +1007,31 @@ static struct genl_ops nl80211_ops[] = { + .flags = GENL_ADMIN_PERM, + .doit = nl80211_del_beacon, + }, ++ { ++ .cmd = NL80211_CMD_GET_STATION, ++ .doit = nl80211_get_station, ++ /* TODO: implement dumpit */ ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = NL80211_CMD_SET_STATION, ++ .doit = nl80211_set_station, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = NL80211_CMD_NEW_STATION, ++ .doit = nl80211_new_station, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ }, ++ { ++ .cmd = NL80211_CMD_DEL_STATION, ++ .doit = nl80211_del_station, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ }, + }; + + /* multicast groups */ -- cgit v1.2.3