aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-05-09 12:41:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-12 14:10:47 -0400
commit56d1893d94bc06d0b1aa3a53f924ed02f9e207bf (patch)
tree90862ae6788cf267631bd9ddebf4bc450d0d2b26 /net/wireless/nl80211.c
parent15cb309614f35df344b9f06a9ea9f077d1e449db (diff)
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)
1876 struct beacon_parameters *info); 1876 struct beacon_parameters *info);
1877 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1877 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1878 struct net_device *dev = info->user_ptr[1]; 1878 struct net_device *dev = info->user_ptr[1];
1879 struct wireless_dev *wdev = dev->ieee80211_ptr;
1879 struct beacon_parameters params; 1880 struct beacon_parameters params;
1880 int haveinfo = 0; 1881 int haveinfo = 0, err;
1881 1882
1882 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1883 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1883 return -EINVAL; 1884 return -EINVAL;
@@ -1886,6 +1887,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1886 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1887 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1887 return -EOPNOTSUPP; 1888 return -EOPNOTSUPP;
1888 1889
1890 memset(&params, 0, sizeof(params));
1891
1889 switch (info->genlhdr->cmd) { 1892 switch (info->genlhdr->cmd) {
1890 case NL80211_CMD_NEW_BEACON: 1893 case NL80211_CMD_NEW_BEACON:
1891 /* these are required for NEW_BEACON */ 1894 /* these are required for NEW_BEACON */
@@ -1894,6 +1897,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1894 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 1897 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1895 return -EINVAL; 1898 return -EINVAL;
1896 1899
1900 params.interval =
1901 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1902 params.dtim_period =
1903 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1904
1905 err = cfg80211_validate_beacon_int(rdev, params.interval);
1906 if (err)
1907 return err;
1908
1897 call = rdev->ops->add_beacon; 1909 call = rdev->ops->add_beacon;
1898 break; 1910 break;
1899 case NL80211_CMD_SET_BEACON: 1911 case NL80211_CMD_SET_BEACON:
@@ -1907,20 +1919,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1907 if (!call) 1919 if (!call)
1908 return -EOPNOTSUPP; 1920 return -EOPNOTSUPP;
1909 1921
1910 memset(&params, 0, sizeof(params));
1911
1912 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1913 params.interval =
1914 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1915 haveinfo = 1;
1916 }
1917
1918 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1919 params.dtim_period =
1920 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1921 haveinfo = 1;
1922 }
1923
1924 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1922 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1925 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 1923 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1926 params.head_len = 1924 params.head_len =
@@ -1938,13 +1936,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1938 if (!haveinfo) 1936 if (!haveinfo)
1939 return -EINVAL; 1937 return -EINVAL;
1940 1938
1941 return call(&rdev->wiphy, dev, &params); 1939 err = call(&rdev->wiphy, dev, &params);
1940 if (!err && params.interval)
1941 wdev->beacon_interval = params.interval;
1942 return err;
1942} 1943}
1943 1944
1944static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 1945static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1945{ 1946{
1946 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1947 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1947 struct net_device *dev = info->user_ptr[1]; 1948 struct net_device *dev = info->user_ptr[1];
1949 struct wireless_dev *wdev = dev->ieee80211_ptr;
1950 int err;
1948 1951
1949 if (!rdev->ops->del_beacon) 1952 if (!rdev->ops->del_beacon)
1950 return -EOPNOTSUPP; 1953 return -EOPNOTSUPP;
@@ -1953,7 +1956,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1953 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1956 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1954 return -EOPNOTSUPP; 1957 return -EOPNOTSUPP;
1955 1958
1956 return rdev->ops->del_beacon(&rdev->wiphy, dev); 1959 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
1960 if (!err)
1961 wdev->beacon_interval = 0;
1962 return err;
1957} 1963}
1958 1964
1959static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 1965static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {