aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c144
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
3114out: 3113out:
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
3184static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) 3183static 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
3258out: 3256out:
3259 cfg80211_put_dev(drv); 3257 cfg80211_put_dev(rdev);
3260 dev_put(dev); 3258 dev_put(dev);
3261unlock_rtnl: 3259unlock_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
3323out: 3318out:
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
3388out: 3380out:
3389 cfg80211_put_dev(drv); 3381 cfg80211_put_dev(drv);