diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 115 |
1 files changed, 71 insertions, 44 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3e7d557fd481..f4d12c71928d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -510,6 +510,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
510 | BIT(NL80211_STA_FLAG_WME) | | 510 | BIT(NL80211_STA_FLAG_WME) | |
511 | BIT(NL80211_STA_FLAG_MFP) | | 511 | BIT(NL80211_STA_FLAG_MFP) | |
512 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 512 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
513 | BIT(NL80211_STA_FLAG_ASSOCIATED) | | ||
513 | BIT(NL80211_STA_FLAG_TDLS_PEER); | 514 | BIT(NL80211_STA_FLAG_TDLS_PEER); |
514 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | 515 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) |
515 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | 516 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); |
@@ -521,6 +522,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
521 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | 522 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); |
522 | if (test_sta_flag(sta, WLAN_STA_AUTH)) | 523 | if (test_sta_flag(sta, WLAN_STA_AUTH)) |
523 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | 524 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); |
525 | if (test_sta_flag(sta, WLAN_STA_ASSOC)) | ||
526 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); | ||
524 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | 527 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) |
525 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | 528 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); |
526 | } | 529 | } |
@@ -1077,6 +1080,58 @@ static void ieee80211_send_layer2_update(struct sta_info *sta) | |||
1077 | netif_rx_ni(skb); | 1080 | netif_rx_ni(skb); |
1078 | } | 1081 | } |
1079 | 1082 | ||
1083 | static int sta_apply_auth_flags(struct ieee80211_local *local, | ||
1084 | struct sta_info *sta, | ||
1085 | u32 mask, u32 set) | ||
1086 | { | ||
1087 | int ret; | ||
1088 | |||
1089 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED) && | ||
1090 | set & BIT(NL80211_STA_FLAG_AUTHENTICATED) && | ||
1091 | !test_sta_flag(sta, WLAN_STA_AUTH)) { | ||
1092 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); | ||
1093 | if (ret) | ||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
1097 | if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) && | ||
1098 | set & BIT(NL80211_STA_FLAG_ASSOCIATED) && | ||
1099 | !test_sta_flag(sta, WLAN_STA_ASSOC)) { | ||
1100 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | ||
1101 | if (ret) | ||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { | ||
1106 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) | ||
1107 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); | ||
1108 | else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
1109 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | ||
1110 | else | ||
1111 | ret = 0; | ||
1112 | if (ret) | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) && | ||
1117 | !(set & BIT(NL80211_STA_FLAG_ASSOCIATED)) && | ||
1118 | test_sta_flag(sta, WLAN_STA_ASSOC)) { | ||
1119 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); | ||
1120 | if (ret) | ||
1121 | return ret; | ||
1122 | } | ||
1123 | |||
1124 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED) && | ||
1125 | !(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) && | ||
1126 | test_sta_flag(sta, WLAN_STA_AUTH)) { | ||
1127 | ret = sta_info_move_state(sta, IEEE80211_STA_NONE); | ||
1128 | if (ret) | ||
1129 | return ret; | ||
1130 | } | ||
1131 | |||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1080 | static int sta_apply_parameters(struct ieee80211_local *local, | 1135 | static int sta_apply_parameters(struct ieee80211_local *local, |
1081 | struct sta_info *sta, | 1136 | struct sta_info *sta, |
1082 | struct station_parameters *params) | 1137 | struct station_parameters *params) |
@@ -1094,52 +1149,20 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1094 | mask = params->sta_flags_mask; | 1149 | mask = params->sta_flags_mask; |
1095 | set = params->sta_flags_set; | 1150 | set = params->sta_flags_set; |
1096 | 1151 | ||
1097 | /* | 1152 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1098 | * In mesh mode, we can clear AUTHENTICATED flag but must | 1153 | /* |
1099 | * also make ASSOCIATED follow appropriately for the driver | 1154 | * In mesh mode, ASSOCIATED isn't part of the nl80211 |
1100 | * API. See also below, after AUTHORIZED changes. | 1155 | * API but must follow AUTHENTICATED for driver state. |
1101 | */ | 1156 | */ |
1102 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | 1157 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) |
1103 | /* cfg80211 should not allow this in non-mesh modes */ | 1158 | mask |= BIT(NL80211_STA_FLAG_ASSOCIATED); |
1104 | if (WARN_ON(!ieee80211_vif_is_mesh(&sdata->vif))) | 1159 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) |
1105 | return -EINVAL; | 1160 | set |= BIT(NL80211_STA_FLAG_ASSOCIATED); |
1106 | |||
1107 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) && | ||
1108 | !test_sta_flag(sta, WLAN_STA_AUTH)) { | ||
1109 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); | ||
1110 | if (ret) | ||
1111 | return ret; | ||
1112 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | ||
1113 | if (ret) | ||
1114 | return ret; | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { | ||
1119 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) | ||
1120 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); | ||
1121 | else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
1122 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | ||
1123 | if (ret) | ||
1124 | return ret; | ||
1125 | } | ||
1126 | |||
1127 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | ||
1128 | /* cfg80211 should not allow this in non-mesh modes */ | ||
1129 | if (WARN_ON(!ieee80211_vif_is_mesh(&sdata->vif))) | ||
1130 | return -EINVAL; | ||
1131 | |||
1132 | if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) && | ||
1133 | test_sta_flag(sta, WLAN_STA_AUTH)) { | ||
1134 | ret = sta_info_move_state(sta, IEEE80211_STA_AUTH); | ||
1135 | if (ret) | ||
1136 | return ret; | ||
1137 | ret = sta_info_move_state(sta, IEEE80211_STA_NONE); | ||
1138 | if (ret) | ||
1139 | return ret; | ||
1140 | } | ||
1141 | } | 1161 | } |
1142 | 1162 | ||
1163 | ret = sta_apply_auth_flags(local, sta, mask, set); | ||
1164 | if (ret) | ||
1165 | return ret; | ||
1143 | 1166 | ||
1144 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { | 1167 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { |
1145 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) | 1168 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) |
@@ -1273,6 +1296,10 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
1273 | if (!sta) | 1296 | if (!sta) |
1274 | return -ENOMEM; | 1297 | return -ENOMEM; |
1275 | 1298 | ||
1299 | /* | ||
1300 | * defaults -- if userspace wants something else we'll | ||
1301 | * change it accordingly in sta_apply_parameters() | ||
1302 | */ | ||
1276 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | 1303 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); |
1277 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); | 1304 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); |
1278 | 1305 | ||