summaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-05-09 18:41:15 +0200
committerJohn W. Linville <linville@tuxdriver.com>2011-05-12 14:10:47 -0400
commit56d1893d94bc06d0b1aa3a53f924ed02f9e207bf (patch)
tree90862ae6788cf267631bd9ddebf4bc450d0d2b26 /net/wireless/nl80211.c
parent15cb309614f35df344b9f06a9ea9f077d1e449db (diff)
downloadlinux-56d1893d94bc06d0b1aa3a53f924ed02f9e207bf.tar.bz2
cfg80211: restrict AP beacon intervals
Multiple virtual AP interfaces can currently try to use different beacon intervals, but that just leads to problems since it won't actually be done that way by drivers. Return an error in this case to make sure it won't be done wrong. Also, ignore attempts to change the DTIM period or beacon interval during the lifetime of the BSS. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b5b050b62f2a..9ef8e287d61b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1876,8 +1876,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
struct beacon_parameters *info);
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
struct beacon_parameters params;
- int haveinfo = 0;
+ int haveinfo = 0, err;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
return -EINVAL;
@@ -1886,6 +1887,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
+ memset(&params, 0, sizeof(params));
+
switch (info->genlhdr->cmd) {
case NL80211_CMD_NEW_BEACON:
/* these are required for NEW_BEACON */
@@ -1894,6 +1897,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
!info->attrs[NL80211_ATTR_BEACON_HEAD])
return -EINVAL;
+ params.interval =
+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+ params.dtim_period =
+ nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+
+ err = cfg80211_validate_beacon_int(rdev, params.interval);
+ if (err)
+ return err;
+
call = rdev->ops->add_beacon;
break;
case NL80211_CMD_SET_BEACON:
@@ -1907,20 +1919,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (!call)
return -EOPNOTSUPP;
- memset(&params, 0, sizeof(params));
-
- if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
- params.interval =
- nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
- haveinfo = 1;
- }
-
- if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
- params.dtim_period =
- nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
- haveinfo = 1;
- }
-
if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
params.head_len =
@@ -1938,13 +1936,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (!haveinfo)
return -EINVAL;
- return call(&rdev->wiphy, dev, &params);
+ err = call(&rdev->wiphy, dev, &params);
+ if (!err && params.interval)
+ wdev->beacon_interval = params.interval;
+ return err;
}
static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ int err;
if (!rdev->ops->del_beacon)
return -EOPNOTSUPP;
@@ -1953,7 +1956,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
- return rdev->ops->del_beacon(&rdev->wiphy, dev);
+ err = rdev->ops->del_beacon(&rdev->wiphy, dev);
+ if (!err)
+ wdev->beacon_interval = 0;
+ return err;
}
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {