diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 144 |
1 files changed, 68 insertions, 76 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0008144b354b..aa2b3f35cc48 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3044,9 +3044,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3044 | { | 3044 | { |
3045 | struct cfg80211_registered_device *drv; | 3045 | struct cfg80211_registered_device *drv; |
3046 | struct net_device *dev; | 3046 | struct net_device *dev; |
3047 | struct cfg80211_auth_request req; | 3047 | struct ieee80211_channel *chan; |
3048 | struct wiphy *wiphy; | 3048 | const u8 *bssid, *ssid, *ie = NULL; |
3049 | int err; | 3049 | int err, ssid_len, ie_len = 0; |
3050 | enum nl80211_auth_type auth_type; | ||
3050 | 3051 | ||
3051 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3052 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3052 | return -EINVAL; | 3053 | return -EINVAL; |
@@ -3057,6 +3058,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3057 | if (!info->attrs[NL80211_ATTR_AUTH_TYPE]) | 3058 | if (!info->attrs[NL80211_ATTR_AUTH_TYPE]) |
3058 | return -EINVAL; | 3059 | return -EINVAL; |
3059 | 3060 | ||
3061 | if (!info->attrs[NL80211_ATTR_SSID]) | ||
3062 | return -EINVAL; | ||
3063 | |||
3064 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) | ||
3065 | return -EINVAL; | ||
3066 | |||
3060 | rtnl_lock(); | 3067 | rtnl_lock(); |
3061 | 3068 | ||
3062 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); | 3069 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); |
@@ -3078,38 +3085,30 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3078 | goto out; | 3085 | goto out; |
3079 | } | 3086 | } |
3080 | 3087 | ||
3081 | wiphy = &drv->wiphy; | 3088 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3082 | memset(&req, 0, sizeof(req)); | 3089 | chan = ieee80211_get_channel(&drv->wiphy, |
3083 | 3090 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | |
3084 | req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3091 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { |
3085 | 3092 | err = -EINVAL; | |
3086 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 3093 | goto out; |
3087 | req.chan = ieee80211_get_channel( | ||
3088 | wiphy, | ||
3089 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | ||
3090 | if (!req.chan) { | ||
3091 | err = -EINVAL; | ||
3092 | goto out; | ||
3093 | } | ||
3094 | } | 3094 | } |
3095 | 3095 | ||
3096 | if (info->attrs[NL80211_ATTR_SSID]) { | 3096 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
3097 | req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 3097 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
3098 | req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | ||
3099 | } | ||
3100 | 3098 | ||
3101 | if (info->attrs[NL80211_ATTR_IE]) { | 3099 | if (info->attrs[NL80211_ATTR_IE]) { |
3102 | req.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 3100 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
3103 | req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3101 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3104 | } | 3102 | } |
3105 | 3103 | ||
3106 | req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); | 3104 | auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); |
3107 | if (!nl80211_valid_auth_type(req.auth_type)) { | 3105 | if (!nl80211_valid_auth_type(auth_type)) { |
3108 | err = -EINVAL; | 3106 | err = -EINVAL; |
3109 | goto out; | 3107 | goto out; |
3110 | } | 3108 | } |
3111 | 3109 | ||
3112 | err = drv->ops->auth(&drv->wiphy, dev, &req); | 3110 | err = cfg80211_mlme_auth(drv, dev, chan, auth_type, bssid, |
3111 | ssid, ssid_len, ie, ie_len); | ||
3113 | 3112 | ||
3114 | out: | 3113 | out: |
3115 | cfg80211_put_dev(drv); | 3114 | cfg80211_put_dev(drv); |
@@ -3183,26 +3182,29 @@ static int nl80211_crypto_settings(struct genl_info *info, | |||
3183 | 3182 | ||
3184 | static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | 3183 | static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) |
3185 | { | 3184 | { |
3186 | struct cfg80211_registered_device *drv; | 3185 | struct cfg80211_registered_device *rdev; |
3187 | struct net_device *dev; | 3186 | struct net_device *dev; |
3188 | struct cfg80211_assoc_request req; | 3187 | struct cfg80211_crypto_settings crypto; |
3189 | struct wiphy *wiphy; | 3188 | struct ieee80211_channel *chan; |
3190 | int err; | 3189 | const u8 *bssid, *ssid, *ie = NULL; |
3190 | int err, ssid_len, ie_len = 0; | ||
3191 | bool use_mfp = false; | ||
3191 | 3192 | ||
3192 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3193 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3193 | return -EINVAL; | 3194 | return -EINVAL; |
3194 | 3195 | ||
3195 | if (!info->attrs[NL80211_ATTR_MAC] || | 3196 | if (!info->attrs[NL80211_ATTR_MAC] || |
3196 | !info->attrs[NL80211_ATTR_SSID]) | 3197 | !info->attrs[NL80211_ATTR_SSID] || |
3198 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | ||
3197 | return -EINVAL; | 3199 | return -EINVAL; |
3198 | 3200 | ||
3199 | rtnl_lock(); | 3201 | rtnl_lock(); |
3200 | 3202 | ||
3201 | err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); | 3203 | err = get_drv_dev_by_info_ifindex(info->attrs, &rdev, &dev); |
3202 | if (err) | 3204 | if (err) |
3203 | goto unlock_rtnl; | 3205 | goto unlock_rtnl; |
3204 | 3206 | ||
3205 | if (!drv->ops->assoc) { | 3207 | if (!rdev->ops->assoc) { |
3206 | err = -EOPNOTSUPP; | 3208 | err = -EOPNOTSUPP; |
3207 | goto out; | 3209 | goto out; |
3208 | } | 3210 | } |
@@ -3217,46 +3219,42 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
3217 | goto out; | 3219 | goto out; |
3218 | } | 3220 | } |
3219 | 3221 | ||
3220 | wiphy = &drv->wiphy; | 3222 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3221 | memset(&req, 0, sizeof(req)); | ||
3222 | |||
3223 | req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
3224 | 3223 | ||
3225 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 3224 | chan = ieee80211_get_channel(&rdev->wiphy, |
3226 | req.chan = ieee80211_get_channel( | 3225 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); |
3227 | wiphy, | 3226 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { |
3228 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | 3227 | err = -EINVAL; |
3229 | if (!req.chan) { | 3228 | goto out; |
3230 | err = -EINVAL; | ||
3231 | goto out; | ||
3232 | } | ||
3233 | } | 3229 | } |
3234 | 3230 | ||
3235 | req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 3231 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
3236 | req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 3232 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
3237 | 3233 | ||
3238 | if (info->attrs[NL80211_ATTR_IE]) { | 3234 | if (info->attrs[NL80211_ATTR_IE]) { |
3239 | req.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 3235 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
3240 | req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3236 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3241 | } | 3237 | } |
3242 | 3238 | ||
3243 | if (info->attrs[NL80211_ATTR_USE_MFP]) { | 3239 | if (info->attrs[NL80211_ATTR_USE_MFP]) { |
3244 | enum nl80211_mfp use_mfp = | 3240 | enum nl80211_mfp use_mfp = |
3245 | nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); | 3241 | nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); |
3246 | if (use_mfp == NL80211_MFP_REQUIRED) | 3242 | if (use_mfp == NL80211_MFP_REQUIRED) |
3247 | req.use_mfp = true; | 3243 | use_mfp = true; |
3248 | else if (use_mfp != NL80211_MFP_NO) { | 3244 | else if (use_mfp != NL80211_MFP_NO) { |
3249 | err = -EINVAL; | 3245 | err = -EINVAL; |
3250 | goto out; | 3246 | goto out; |
3251 | } | 3247 | } |
3252 | } | 3248 | } |
3253 | 3249 | ||
3254 | err = nl80211_crypto_settings(info, &req.crypto); | 3250 | err = nl80211_crypto_settings(info, &crypto); |
3255 | if (!err) | 3251 | if (!err) |
3256 | err = drv->ops->assoc(&drv->wiphy, dev, &req); | 3252 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, ssid, |
3253 | ssid_len, ie, ie_len, use_mfp, | ||
3254 | &crypto); | ||
3257 | 3255 | ||
3258 | out: | 3256 | out: |
3259 | cfg80211_put_dev(drv); | 3257 | cfg80211_put_dev(rdev); |
3260 | dev_put(dev); | 3258 | dev_put(dev); |
3261 | unlock_rtnl: | 3259 | unlock_rtnl: |
3262 | rtnl_unlock(); | 3260 | rtnl_unlock(); |
@@ -3267,9 +3265,9 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3267 | { | 3265 | { |
3268 | struct cfg80211_registered_device *drv; | 3266 | struct cfg80211_registered_device *drv; |
3269 | struct net_device *dev; | 3267 | struct net_device *dev; |
3270 | struct cfg80211_deauth_request req; | 3268 | const u8 *ie = NULL, *bssid; |
3271 | struct wiphy *wiphy; | 3269 | int err, ie_len = 0; |
3272 | int err; | 3270 | u16 reason_code; |
3273 | 3271 | ||
3274 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3272 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3275 | return -EINVAL; | 3273 | return -EINVAL; |
@@ -3301,24 +3299,21 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3301 | goto out; | 3299 | goto out; |
3302 | } | 3300 | } |
3303 | 3301 | ||
3304 | wiphy = &drv->wiphy; | 3302 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3305 | memset(&req, 0, sizeof(req)); | ||
3306 | |||
3307 | req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
3308 | 3303 | ||
3309 | req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | 3304 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); |
3310 | if (req.reason_code == 0) { | 3305 | if (reason_code == 0) { |
3311 | /* Reason Code 0 is reserved */ | 3306 | /* Reason Code 0 is reserved */ |
3312 | err = -EINVAL; | 3307 | err = -EINVAL; |
3313 | goto out; | 3308 | goto out; |
3314 | } | 3309 | } |
3315 | 3310 | ||
3316 | if (info->attrs[NL80211_ATTR_IE]) { | 3311 | if (info->attrs[NL80211_ATTR_IE]) { |
3317 | req.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 3312 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
3318 | req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3313 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3319 | } | 3314 | } |
3320 | 3315 | ||
3321 | err = drv->ops->deauth(&drv->wiphy, dev, &req); | 3316 | err = cfg80211_mlme_deauth(drv, dev, bssid, ie, ie_len, reason_code); |
3322 | 3317 | ||
3323 | out: | 3318 | out: |
3324 | cfg80211_put_dev(drv); | 3319 | cfg80211_put_dev(drv); |
@@ -3332,9 +3327,9 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3332 | { | 3327 | { |
3333 | struct cfg80211_registered_device *drv; | 3328 | struct cfg80211_registered_device *drv; |
3334 | struct net_device *dev; | 3329 | struct net_device *dev; |
3335 | struct cfg80211_disassoc_request req; | 3330 | const u8 *ie = NULL, *bssid; |
3336 | struct wiphy *wiphy; | 3331 | int err, ie_len = 0; |
3337 | int err; | 3332 | u16 reason_code; |
3338 | 3333 | ||
3339 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3334 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3340 | return -EINVAL; | 3335 | return -EINVAL; |
@@ -3366,24 +3361,21 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3366 | goto out; | 3361 | goto out; |
3367 | } | 3362 | } |
3368 | 3363 | ||
3369 | wiphy = &drv->wiphy; | 3364 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3370 | memset(&req, 0, sizeof(req)); | ||
3371 | |||
3372 | req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
3373 | 3365 | ||
3374 | req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | 3366 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); |
3375 | if (req.reason_code == 0) { | 3367 | if (reason_code == 0) { |
3376 | /* Reason Code 0 is reserved */ | 3368 | /* Reason Code 0 is reserved */ |
3377 | err = -EINVAL; | 3369 | err = -EINVAL; |
3378 | goto out; | 3370 | goto out; |
3379 | } | 3371 | } |
3380 | 3372 | ||
3381 | if (info->attrs[NL80211_ATTR_IE]) { | 3373 | if (info->attrs[NL80211_ATTR_IE]) { |
3382 | req.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 3374 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
3383 | req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3375 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3384 | } | 3376 | } |
3385 | 3377 | ||
3386 | err = drv->ops->disassoc(&drv->wiphy, dev, &req); | 3378 | err = cfg80211_mlme_disassoc(drv, dev, bssid, ie, ie_len, reason_code); |
3387 | 3379 | ||
3388 | out: | 3380 | out: |
3389 | cfg80211_put_dev(drv); | 3381 | cfg80211_put_dev(drv); |