|
@@ -3412,7 +3412,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
memset(¶ms, 0, sizeof(params));
|
|
|
|
|
|
params.listen_interval = -1;
|
|
|
- params.plink_state = -1;
|
|
|
|
|
|
if (info->attrs[NL80211_ATTR_STA_AID])
|
|
|
return -EINVAL;
|
|
@@ -3451,13 +3450,20 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
|
|
|
params.plink_action =
|
|
|
- nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
|
+ nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
|
+ if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- if (info->attrs[NL80211_ATTR_STA_PLINK_STATE])
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
|
|
|
params.plink_state =
|
|
|
- nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
|
|
|
+ nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
|
|
|
+ if (params.plink_state >= NUM_NL80211_PLINK_STATES)
|
|
|
+ return -EINVAL;
|
|
|
+ params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
|
|
|
+ }
|
|
|
|
|
|
if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
|
|
|
enum nl80211_mesh_power_mode pm = nla_get_u32(
|
|
@@ -3479,6 +3485,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
return -EINVAL;
|
|
|
if (params.local_pm)
|
|
|
return -EINVAL;
|
|
|
+ if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/* TDLS can't be set, ... */
|
|
|
if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
|
@@ -3542,6 +3550,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
return -EINVAL;
|
|
|
if (params.local_pm)
|
|
|
return -EINVAL;
|
|
|
+ if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
|
|
|
+ return -EINVAL;
|
|
|
/* reject any changes other than AUTHORIZED or WME (for TDLS) */
|
|
|
if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
|
|
|
BIT(NL80211_STA_FLAG_WME)))
|
|
@@ -3553,6 +3563,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
return -EINVAL;
|
|
|
if (params.local_pm)
|
|
|
return -EINVAL;
|
|
|
+ if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
|
|
|
+ return -EINVAL;
|
|
|
if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
|
|
|
info->attrs[NL80211_ATTR_VHT_CAPABILITY])
|
|
|
return -EINVAL;
|
|
@@ -3652,9 +3664,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
|
|
params.vht_capa =
|
|
|
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
|
|
|
|
|
|
- if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
|
|
|
+ if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
|
|
|
params.plink_action =
|
|
|
- nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
|
+ nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
|
|
|
+ if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
if (!rdev->ops->add_station)
|
|
|
return -EOPNOTSUPP;
|