|
@@ -368,6 +368,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|
|
[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
|
|
|
[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
|
|
|
[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
|
|
|
+ [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
|
|
|
+ [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
|
|
|
};
|
|
|
|
|
|
/* policy for the key attributes */
|
|
@@ -3435,6 +3437,19 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
|
|
|
}
|
|
|
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
|
|
|
+ params.capability =
|
|
|
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
|
|
|
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
|
|
|
+ params.ext_capab =
|
|
|
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
|
|
|
+ params.ext_capab_len =
|
|
|
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
|
|
|
+ }
|
|
|
+
|
|
|
if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] ||
|
|
|
info->attrs[NL80211_ATTR_HT_CAPABILITY])
|
|
|
return -EINVAL;
|
|
@@ -3505,6 +3520,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
/* reject other things that can't change */
|
|
|
if (params.supported_rates)
|
|
|
return -EINVAL;
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
|
|
|
+ return -EINVAL;
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/* must be last in here for error handling */
|
|
|
params.vlan = get_vlan(info, rdev);
|
|
@@ -3537,6 +3556,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
return -EINVAL;
|
|
|
if (params.supported_rates)
|
|
|
return -EINVAL;
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
|
|
|
+ return -EINVAL;
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
|
|
|
+ return -EINVAL;
|
|
|
/*
|
|
|
* No special handling for TDLS here -- the userspace
|
|
|
* mesh code doesn't have this bug.
|
|
@@ -3601,6 +3624,19 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (!params.aid || params.aid > IEEE80211_MAX_AID)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
|
|
|
+ params.capability =
|
|
|
+ nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
|
|
|
+ params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
|
|
|
+ params.ext_capab =
|
|
|
+ nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
|
|
|
+ params.ext_capab_len =
|
|
|
+ nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
|
|
|
+ }
|
|
|
+
|
|
|
if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
|
|
|
params.ht_capa =
|
|
|
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
|