diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-02-14 17:27:01 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-03-06 10:35:37 -0500 |
commit | f8bacc210408f7a2a182f184a9fa1475b8a67440 (patch) | |
tree | 714bcf6b0240c622f9affb6ff7df61b4f9dc87a9 | |
parent | c0f3a317f2f0e51ad2f8809c83b137958b385c7f (diff) |
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>
-rw-r--r-- | include/net/cfg80211.h | 15 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 20 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 14 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 29 |
4 files changed, 54 insertions, 24 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d581c6de5d64..9b54574c3df9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -611,22 +611,10 @@ struct cfg80211_ap_settings { | |||
611 | }; | 611 | }; |
612 | 612 | ||
613 | /** | 613 | /** |
614 | * enum plink_action - actions to perform in mesh peers | ||
615 | * | ||
616 | * @PLINK_ACTION_INVALID: action 0 is reserved | ||
617 | * @PLINK_ACTION_OPEN: start mesh peer link establishment | ||
618 | * @PLINK_ACTION_BLOCK: block traffic from this mesh peer | ||
619 | */ | ||
620 | enum plink_actions { | ||
621 | PLINK_ACTION_INVALID, | ||
622 | PLINK_ACTION_OPEN, | ||
623 | PLINK_ACTION_BLOCK, | ||
624 | }; | ||
625 | |||
626 | /** | ||
627 | * enum station_parameters_apply_mask - station parameter values to apply | 614 | * enum station_parameters_apply_mask - station parameter values to apply |
628 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) | 615 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) |
629 | * @STATION_PARAM_APPLY_CAPABILITY: apply new capability | 616 | * @STATION_PARAM_APPLY_CAPABILITY: apply new capability |
617 | * @STATION_PARAM_APPLY_PLINK_STATE: apply new plink state | ||
630 | * | 618 | * |
631 | * Not all station parameters have in-band "no change" signalling, | 619 | * Not all station parameters have in-band "no change" signalling, |
632 | * for those that don't these flags will are used. | 620 | * for those that don't these flags will are used. |
@@ -634,6 +622,7 @@ enum plink_actions { | |||
634 | enum station_parameters_apply_mask { | 622 | enum station_parameters_apply_mask { |
635 | STATION_PARAM_APPLY_UAPSD = BIT(0), | 623 | STATION_PARAM_APPLY_UAPSD = BIT(0), |
636 | STATION_PARAM_APPLY_CAPABILITY = BIT(1), | 624 | STATION_PARAM_APPLY_CAPABILITY = BIT(1), |
625 | STATION_PARAM_APPLY_PLINK_STATE = BIT(2), | ||
637 | }; | 626 | }; |
638 | 627 | ||
639 | /** | 628 | /** |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index c46bb016f4e4..7dcc69f73d2c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -884,7 +884,8 @@ enum nl80211_commands { | |||
884 | * consisting of a nested array. | 884 | * consisting of a nested array. |
885 | * | 885 | * |
886 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). | 886 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). |
887 | * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link. | 887 | * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link |
888 | * (see &enum nl80211_plink_action). | ||
888 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. | 889 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. |
889 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path | 890 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path |
890 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at | 891 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at |
@@ -3307,6 +3308,23 @@ enum nl80211_plink_state { | |||
3307 | MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 | 3308 | MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 |
3308 | }; | 3309 | }; |
3309 | 3310 | ||
3311 | /** | ||
3312 | * enum nl80211_plink_action - actions to perform in mesh peers | ||
3313 | * | ||
3314 | * @NL80211_PLINK_ACTION_NO_ACTION: perform no action | ||
3315 | * @NL80211_PLINK_ACTION_OPEN: start mesh peer link establishment | ||
3316 | * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer | ||
3317 | * @NUM_NL80211_PLINK_ACTIONS: number of possible actions | ||
3318 | */ | ||
3319 | enum plink_actions { | ||
3320 | NL80211_PLINK_ACTION_NO_ACTION, | ||
3321 | NL80211_PLINK_ACTION_OPEN, | ||
3322 | NL80211_PLINK_ACTION_BLOCK, | ||
3323 | |||
3324 | NUM_NL80211_PLINK_ACTIONS, | ||
3325 | }; | ||
3326 | |||
3327 | |||
3310 | #define NL80211_KCK_LEN 16 | 3328 | #define NL80211_KCK_LEN 16 |
3311 | #define NL80211_KEK_LEN 16 | 3329 | #define NL80211_KEK_LEN 16 |
3312 | #define NL80211_REPLAY_CTR_LEN 8 | 3330 | #define NL80211_REPLAY_CTR_LEN 8 |
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, | |||
1261 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1261 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1262 | #ifdef CONFIG_MAC80211_MESH | 1262 | #ifdef CONFIG_MAC80211_MESH |
1263 | u32 changed = 0; | 1263 | u32 changed = 0; |
1264 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) { | 1264 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED && |
1265 | (params->sta_modify_mask & | ||
1266 | STATION_PARAM_APPLY_PLINK_STATE)) { | ||
1265 | switch (params->plink_state) { | 1267 | switch (params->plink_state) { |
1266 | case NL80211_PLINK_ESTAB: | 1268 | case NL80211_PLINK_ESTAB: |
1267 | if (sta->plink_state != NL80211_PLINK_ESTAB) | 1269 | if (sta->plink_state != NL80211_PLINK_ESTAB) |
@@ -1292,12 +1294,18 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1292 | /* nothing */ | 1294 | /* nothing */ |
1293 | break; | 1295 | break; |
1294 | } | 1296 | } |
1297 | } else if (params->sta_modify_mask & | ||
1298 | STATION_PARAM_APPLY_PLINK_STATE) { | ||
1299 | return -EINVAL; | ||
1295 | } else { | 1300 | } else { |
1296 | switch (params->plink_action) { | 1301 | switch (params->plink_action) { |
1297 | case PLINK_ACTION_OPEN: | 1302 | case NL80211_PLINK_ACTION_NO_ACTION: |
1303 | /* nothing */ | ||
1304 | break; | ||
1305 | case NL80211_PLINK_ACTION_OPEN: | ||
1298 | changed |= mesh_plink_open(sta); | 1306 | changed |= mesh_plink_open(sta); |
1299 | break; | 1307 | break; |
1300 | case PLINK_ACTION_BLOCK: | 1308 | case NL80211_PLINK_ACTION_BLOCK: |
1301 | changed |= mesh_plink_block(sta); | 1309 | changed |= mesh_plink_block(sta); |
1302 | break; | 1310 | break; |
1303 | } | 1311 | } |
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) | |||
3412 | memset(¶ms, 0, sizeof(params)); | 3412 | memset(¶ms, 0, sizeof(params)); |
3413 | 3413 | ||
3414 | params.listen_interval = -1; | 3414 | params.listen_interval = -1; |
3415 | params.plink_state = -1; | ||
3416 | 3415 | ||
3417 | if (info->attrs[NL80211_ATTR_STA_AID]) | 3416 | if (info->attrs[NL80211_ATTR_STA_AID]) |
3418 | return -EINVAL; | 3417 | return -EINVAL; |
@@ -3451,13 +3450,20 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3451 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) | 3450 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
3452 | return -EINVAL; | 3451 | return -EINVAL; |
3453 | 3452 | ||
3454 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 3453 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) { |
3455 | params.plink_action = | 3454 | params.plink_action = |
3456 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 3455 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
3456 | if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS) | ||
3457 | return -EINVAL; | ||
3458 | } | ||
3457 | 3459 | ||
3458 | if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) | 3460 | if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) { |
3459 | params.plink_state = | 3461 | params.plink_state = |
3460 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); | 3462 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); |
3463 | if (params.plink_state >= NUM_NL80211_PLINK_STATES) | ||
3464 | return -EINVAL; | ||
3465 | params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE; | ||
3466 | } | ||
3461 | 3467 | ||
3462 | if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { | 3468 | if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { |
3463 | enum nl80211_mesh_power_mode pm = nla_get_u32( | 3469 | 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) | |||
3479 | return -EINVAL; | 3485 | return -EINVAL; |
3480 | if (params.local_pm) | 3486 | if (params.local_pm) |
3481 | return -EINVAL; | 3487 | return -EINVAL; |
3488 | if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | ||
3489 | return -EINVAL; | ||
3482 | 3490 | ||
3483 | /* TDLS can't be set, ... */ | 3491 | /* TDLS can't be set, ... */ |
3484 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 3492 | 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) | |||
3542 | return -EINVAL; | 3550 | return -EINVAL; |
3543 | if (params.local_pm) | 3551 | if (params.local_pm) |
3544 | return -EINVAL; | 3552 | return -EINVAL; |
3553 | if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | ||
3554 | return -EINVAL; | ||
3545 | /* reject any changes other than AUTHORIZED or WME (for TDLS) */ | 3555 | /* reject any changes other than AUTHORIZED or WME (for TDLS) */ |
3546 | if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | | 3556 | if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | |
3547 | BIT(NL80211_STA_FLAG_WME))) | 3557 | BIT(NL80211_STA_FLAG_WME))) |
@@ -3553,6 +3563,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3553 | return -EINVAL; | 3563 | return -EINVAL; |
3554 | if (params.local_pm) | 3564 | if (params.local_pm) |
3555 | return -EINVAL; | 3565 | return -EINVAL; |
3566 | if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | ||
3567 | return -EINVAL; | ||
3556 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || | 3568 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || |
3557 | info->attrs[NL80211_ATTR_VHT_CAPABILITY]) | 3569 | info->attrs[NL80211_ATTR_VHT_CAPABILITY]) |
3558 | return -EINVAL; | 3570 | return -EINVAL; |
@@ -3652,9 +3664,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
3652 | params.vht_capa = | 3664 | params.vht_capa = |
3653 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); | 3665 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); |
3654 | 3666 | ||
3655 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 3667 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) { |
3656 | params.plink_action = | 3668 | params.plink_action = |
3657 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 3669 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
3670 | if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS) | ||
3671 | return -EINVAL; | ||
3672 | } | ||
3658 | 3673 | ||
3659 | if (!rdev->ops->add_station) | 3674 | if (!rdev->ops->add_station) |
3660 | return -EOPNOTSUPP; | 3675 | return -EOPNOTSUPP; |