summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-14 23:27:01 +0100
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 16:35:37 +0100
commitf8bacc210408f7a2a182f184a9fa1475b8a67440 (patch)
tree714bcf6b0240c622f9affb6ff7df61b4f9dc87a9 /net
parentc0f3a317f2f0e51ad2f8809c83b137958b385c7f (diff)
downloadblackbird-obmc-linux-f8bacc210408f7a2a182f184a9fa1475b8a67440.tar.gz
blackbird-obmc-linux-f8bacc210408f7a2a182f184a9fa1475b8a67440.zip
cfg80211: clean up mesh plink station change API
Make the ability to leave the plink_state unchanged not use a magic -1 variable that isn't in the enum, but an explicit change flag; reject invalid plink states or actions and move the needed constants for plink actions to the right header file. Also reject plink_state changes for non-mesh interfaces. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/wireless/nl80211.c29
2 files changed, 33 insertions, 10 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fb306814576a..ca28405d5f65 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1261,7 +1261,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
u32 changed = 0;
- if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) {
+ if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED &&
+ (params->sta_modify_mask &
+ STATION_PARAM_APPLY_PLINK_STATE)) {
switch (params->plink_state) {
case NL80211_PLINK_ESTAB:
if (sta->plink_state != NL80211_PLINK_ESTAB)
@@ -1292,12 +1294,18 @@ static int sta_apply_parameters(struct ieee80211_local *local,
/* nothing */
break;
}
+ } else if (params->sta_modify_mask &
+ STATION_PARAM_APPLY_PLINK_STATE) {
+ return -EINVAL;
} else {
switch (params->plink_action) {
- case PLINK_ACTION_OPEN:
+ case NL80211_PLINK_ACTION_NO_ACTION:
+ /* nothing */
+ break;
+ case NL80211_PLINK_ACTION_OPEN:
changed |= mesh_plink_open(sta);
break;
- case PLINK_ACTION_BLOCK:
+ case NL80211_PLINK_ACTION_BLOCK:
changed |= mesh_plink_block(sta);
break;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d44ab216c0ec..9e7ece0e5e5e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3412,7 +3412,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
memset(&params, 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, &params))
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;
OpenPOWER on IntegriCloud