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.
Unified · Split
| @@ -610,23 +610,11 @@ struct cfg80211_ap_settings { · 609 unmodified lines | ||
| 610 | 610 | bool radar_required; |
| 611 | 611 | }; |
| 612 | 612 | |
| 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 | 613 | /** |
| 627 | 614 | * enum station_parameters_apply_mask - station parameter values to apply |
| 628 | 615 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) |
| 629 | 616 | * @STATION_PARAM_APPLY_CAPABILITY: apply new capability |
| 617 | + * @STATION_PARAM_APPLY_PLINK_STATE: apply new plink state | |
| 630 | 618 | * |
| 631 | 619 | * Not all station parameters have in-band "no change" signalling, |
| 632 | 620 | * for those that don't these flags will are used. |
| @@ -634,6 +622,7 @@ enum plink_actions { · 1 unmodified line | ||
| 634 | 622 | enum station_parameters_apply_mask { |
| 635 | 623 | STATION_PARAM_APPLY_UAPSD = BIT(0), |
| 636 | 624 | STATION_PARAM_APPLY_CAPABILITY = BIT(1), |
| 625 | + STATION_PARAM_APPLY_PLINK_STATE = BIT(2), | |
| 637 | 626 | }; |
| 638 | 627 | |
| 639 | 628 | /** |
| @@ -884,7 +884,8 @@ enum nl80211_commands { · 883 unmodified lines | ||
| 884 | 884 | * consisting of a nested array. |
| 885 | 885 | * |
| 886 | 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 | 889 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. |
| 889 | 890 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path |
| 890 | 891 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at |
| @@ -3307,6 +3308,23 @@ enum nl80211_plink_state { · 2416 unmodified lines | ||
| 3307 | 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 | 3328 | #define NL80211_KCK_LEN 16 |
| 3311 | 3329 | #define NL80211_KEK_LEN 16 |
| 3312 | 3330 | #define NL80211_REPLAY_CTR_LEN 8 |
| @@ -1261,7 +1261,9 @@ static int sta_apply_parameters(struct ieee80211_local *local, · 1260 unmodified lines | ||
| 1261 | 1261 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
| 1262 | 1262 | #ifdef CONFIG_MAC80211_MESH |
| 1263 | 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 | 1267 | switch (params->plink_state) { |
| 1266 | 1268 | case NL80211_PLINK_ESTAB: |
| 1267 | 1269 | if (sta->plink_state != NL80211_PLINK_ESTAB) |
| @@ -1292,12 +1294,18 @@ static int sta_apply_parameters(struct ieee80211_local *local, · 24 unmodified lines | ||
| 1292 | 1294 | /* nothing */ |
| 1293 | 1295 | break; |
| 1294 | 1296 | } |
| 1297 | + } else if (params->sta_modify_mask & | |
| 1298 | + STATION_PARAM_APPLY_PLINK_STATE) { | |
| 1299 | + return -EINVAL; | |
| 1295 | 1300 | } else { |
| 1296 | 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 | 1306 | changed |= mesh_plink_open(sta); |
| 1299 | 1307 | break; |
| 1300 | − case PLINK_ACTION_BLOCK: | |
| 1308 | + case NL80211_PLINK_ACTION_BLOCK: | |
| 1301 | 1309 | changed |= mesh_plink_block(sta); |
| 1302 | 1310 | break; |
| 1303 | 1311 | } |
| @@ -3412,7 +3412,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) · 3411 unmodified lines | ||
| 3412 | 3412 | memset(¶ms, 0, sizeof(params)); |
| 3413 | 3413 | |
| 3414 | 3414 | params.listen_interval = -1; |
| 3415 | − params.plink_state = -1; | |
| 3416 | 3415 | |
| 3417 | 3416 | if (info->attrs[NL80211_ATTR_STA_AID]) |
| 3418 | 3417 | return -EINVAL; |
| @@ -3451,13 +3450,20 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) · 32 unmodified lines | ||
| 3451 | 3450 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
| 3452 | 3451 | return -EINVAL; |
| 3453 | 3452 | |
| 3454 | − if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | |
| 3453 | + if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) { | |
| 3455 | 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 | 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 | 3468 | if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { |
| 3463 | 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) · 15 unmodified lines | ||
| 3479 | 3485 | return -EINVAL; |
| 3480 | 3486 | if (params.local_pm) |
| 3481 | 3487 | return -EINVAL; |
| 3488 | + if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | |
| 3489 | + return -EINVAL; | |
| 3482 | 3490 | |
| 3483 | 3491 | /* TDLS can't be set, ... */ |
| 3484 | 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) · 57 unmodified lines | ||
| 3542 | 3550 | return -EINVAL; |
| 3543 | 3551 | if (params.local_pm) |
| 3544 | 3552 | return -EINVAL; |
| 3553 | + if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | |
| 3554 | + return -EINVAL; | |
| 3545 | 3555 | /* reject any changes other than AUTHORIZED or WME (for TDLS) */ |
| 3546 | 3556 | if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | |
| 3547 | 3557 | BIT(NL80211_STA_FLAG_WME))) |
| @@ -3553,6 +3563,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) · 5 unmodified lines | ||
| 3553 | 3563 | return -EINVAL; |
| 3554 | 3564 | if (params.local_pm) |
| 3555 | 3565 | return -EINVAL; |
| 3566 | + if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) | |
| 3567 | + return -EINVAL; | |
| 3556 | 3568 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || |
| 3557 | 3569 | info->attrs[NL80211_ATTR_VHT_CAPABILITY]) |
| 3558 | 3570 | return -EINVAL; |
| @@ -3652,9 +3664,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) · 93 unmodified lines | ||
| 3652 | 3664 | params.vht_capa = |
| 3653 | 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 | 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 | 3674 | if (!rdev->ops->add_station) |
| 3660 | 3675 | return -EOPNOTSUPP; |