diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2353ddbf4934..66024ef57bab 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -123,6 +123,9 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
123 | [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, | 123 | [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, |
124 | [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, | 124 | [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, |
125 | [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 }, | 125 | [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 }, |
126 | [NL80211_ATTR_STA_FLAGS2] = { | ||
127 | .len = sizeof(struct nl80211_sta_flag_update), | ||
128 | }, | ||
126 | }; | 129 | }; |
127 | 130 | ||
128 | /* IE validation */ | 131 | /* IE validation */ |
@@ -1334,13 +1337,33 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { | |||
1334 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, | 1337 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, |
1335 | }; | 1338 | }; |
1336 | 1339 | ||
1337 | static int parse_station_flags(struct nlattr *nla, u32 *staflags) | 1340 | static int parse_station_flags(struct genl_info *info, |
1341 | struct station_parameters *params) | ||
1338 | { | 1342 | { |
1339 | struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; | 1343 | struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; |
1344 | struct nlattr *nla; | ||
1340 | int flag; | 1345 | int flag; |
1341 | 1346 | ||
1342 | *staflags = 0; | 1347 | /* |
1348 | * Try parsing the new attribute first so userspace | ||
1349 | * can specify both for older kernels. | ||
1350 | */ | ||
1351 | nla = info->attrs[NL80211_ATTR_STA_FLAGS2]; | ||
1352 | if (nla) { | ||
1353 | struct nl80211_sta_flag_update *sta_flags; | ||
1354 | |||
1355 | sta_flags = nla_data(nla); | ||
1356 | params->sta_flags_mask = sta_flags->mask; | ||
1357 | params->sta_flags_set = sta_flags->set; | ||
1358 | if ((params->sta_flags_mask | | ||
1359 | params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID)) | ||
1360 | return -EINVAL; | ||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | /* if present, parse the old attribute */ | ||
1343 | 1365 | ||
1366 | nla = info->attrs[NL80211_ATTR_STA_FLAGS]; | ||
1344 | if (!nla) | 1367 | if (!nla) |
1345 | return 0; | 1368 | return 0; |
1346 | 1369 | ||
@@ -1348,11 +1371,12 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags) | |||
1348 | nla, sta_flags_policy)) | 1371 | nla, sta_flags_policy)) |
1349 | return -EINVAL; | 1372 | return -EINVAL; |
1350 | 1373 | ||
1351 | *staflags = STATION_FLAG_CHANGED; | 1374 | params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1; |
1375 | params->sta_flags_mask &= ~1; | ||
1352 | 1376 | ||
1353 | for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) | 1377 | for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) |
1354 | if (flags[flag]) | 1378 | if (flags[flag]) |
1355 | *staflags |= (1<<flag); | 1379 | params->sta_flags_set |= (1<<flag); |
1356 | 1380 | ||
1357 | return 0; | 1381 | return 0; |
1358 | } | 1382 | } |
@@ -1648,8 +1672,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
1648 | params.ht_capa = | 1672 | params.ht_capa = |
1649 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 1673 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
1650 | 1674 | ||
1651 | if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], | 1675 | if (parse_station_flags(info, ¶ms)) |
1652 | ¶ms.station_flags)) | ||
1653 | return -EINVAL; | 1676 | return -EINVAL; |
1654 | 1677 | ||
1655 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 1678 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) |
@@ -1718,8 +1741,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1718 | params.ht_capa = | 1741 | params.ht_capa = |
1719 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 1742 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
1720 | 1743 | ||
1721 | if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], | 1744 | if (parse_station_flags(info, ¶ms)) |
1722 | ¶ms.station_flags)) | ||
1723 | return -EINVAL; | 1745 | return -EINVAL; |
1724 | 1746 | ||
1725 | rtnl_lock(); | 1747 | rtnl_lock(); |