1 /* 2 * cfg80211 MLME SAP interface 3 * 4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/netdevice.h> 10 #include <linux/nl80211.h> 11 #include <linux/slab.h> 12 #include <linux/wireless.h> 13 #include <net/cfg80211.h> 14 #include <net/iw_handler.h> 15 #include "core.h" 16 #include "nl80211.h" 17 18 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) 19 { 20 struct wireless_dev *wdev = dev->ieee80211_ptr; 21 struct wiphy *wiphy = wdev->wiphy; 22 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 23 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 24 u8 *bssid = mgmt->bssid; 25 int i; 26 u16 status = le16_to_cpu(mgmt->u.auth.status_code); 27 bool done = false; 28 29 wdev_lock(wdev); 30 31 for (i = 0; i < MAX_AUTH_BSSES; i++) { 32 if (wdev->authtry_bsses[i] && 33 memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, 34 ETH_ALEN) == 0) { 35 if (status == WLAN_STATUS_SUCCESS) { 36 wdev->auth_bsses[i] = wdev->authtry_bsses[i]; 37 } else { 38 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 39 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 40 } 41 wdev->authtry_bsses[i] = NULL; 42 done = true; 43 break; 44 } 45 } 46 47 if (done) { 48 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); 49 cfg80211_sme_rx_auth(dev, buf, len); 50 } 51 52 wdev_unlock(wdev); 53 } 54 EXPORT_SYMBOL(cfg80211_send_rx_auth); 55 56 void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) 57 { 58 u16 status_code; 59 struct wireless_dev *wdev = dev->ieee80211_ptr; 60 struct wiphy *wiphy = wdev->wiphy; 61 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 62 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 63 u8 *ie = mgmt->u.assoc_resp.variable; 64 int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 65 struct cfg80211_internal_bss *bss = NULL; 66 67 wdev_lock(wdev); 68 69 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 70 71 /* 72 * This is a bit of a hack, we don't notify userspace of 73 * a (re-)association reply if we tried to send a reassoc 74 * and got a reject -- we only try again with an assoc 75 * frame instead of reassoc. 76 */ 77 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 78 cfg80211_sme_failed_reassoc(wdev)) 79 goto out; 80 81 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 82 83 if (status_code == WLAN_STATUS_SUCCESS) { 84 for (i = 0; i < MAX_AUTH_BSSES; i++) { 85 if (!wdev->auth_bsses[i]) 86 continue; 87 if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid, 88 ETH_ALEN) == 0) { 89 bss = wdev->auth_bsses[i]; 90 wdev->auth_bsses[i] = NULL; 91 /* additional reference to drop hold */ 92 cfg80211_ref_bss(bss); 93 break; 94 } 95 } 96 97 /* 98 * We might be coming here because the driver reported 99 * a successful association at the same time as the 100 * user requested a deauth. In that case, we will have 101 * removed the BSS from the auth_bsses list due to the 102 * deauth request when the assoc response makes it. If 103 * the two code paths acquire the lock the other way 104 * around, that's just the standard situation of a 105 * deauth being requested while connected. 106 */ 107 if (!bss) 108 goto out; 109 } else if (wdev->conn) { 110 cfg80211_sme_failed_assoc(wdev); 111 /* 112 * do not call connect_result() now because the 113 * sme will schedule work that does it later. 114 */ 115 goto out; 116 } 117 118 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 119 /* 120 * This is for the userspace SME, the CONNECTING 121 * state will be changed to CONNECTED by 122 * __cfg80211_connect_result() below. 123 */ 124 wdev->sme_state = CFG80211_SME_CONNECTING; 125 } 126 127 /* this consumes one bss reference (unless bss is NULL) */ 128 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 129 status_code, 130 status_code == WLAN_STATUS_SUCCESS, 131 bss ? &bss->pub : NULL); 132 /* drop hold now, and also reference acquired above */ 133 if (bss) { 134 cfg80211_unhold_bss(bss); 135 cfg80211_put_bss(&bss->pub); 136 } 137 138 out: 139 wdev_unlock(wdev); 140 } 141 EXPORT_SYMBOL(cfg80211_send_rx_assoc); 142 143 void __cfg80211_send_deauth(struct net_device *dev, 144 const u8 *buf, size_t len) 145 { 146 struct wireless_dev *wdev = dev->ieee80211_ptr; 147 struct wiphy *wiphy = wdev->wiphy; 148 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 149 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 150 const u8 *bssid = mgmt->bssid; 151 int i; 152 bool found = false, was_current = false; 153 154 ASSERT_WDEV_LOCK(wdev); 155 156 if (wdev->current_bss && 157 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 158 cfg80211_unhold_bss(wdev->current_bss); 159 cfg80211_put_bss(&wdev->current_bss->pub); 160 wdev->current_bss = NULL; 161 found = true; 162 was_current = true; 163 } else for (i = 0; i < MAX_AUTH_BSSES; i++) { 164 if (wdev->auth_bsses[i] && 165 memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { 166 cfg80211_unhold_bss(wdev->auth_bsses[i]); 167 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 168 wdev->auth_bsses[i] = NULL; 169 found = true; 170 break; 171 } 172 if (wdev->authtry_bsses[i] && 173 memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, 174 ETH_ALEN) == 0 && 175 memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) { 176 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 177 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 178 wdev->authtry_bsses[i] = NULL; 179 found = true; 180 break; 181 } 182 } 183 184 if (!found) 185 return; 186 187 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL); 188 189 if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) { 190 u16 reason_code; 191 bool from_ap; 192 193 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 194 195 from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0; 196 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 197 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { 198 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 199 WLAN_STATUS_UNSPECIFIED_FAILURE, 200 false, NULL); 201 } 202 } 203 EXPORT_SYMBOL(__cfg80211_send_deauth); 204 205 void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len) 206 { 207 struct wireless_dev *wdev = dev->ieee80211_ptr; 208 209 wdev_lock(wdev); 210 __cfg80211_send_deauth(dev, buf, len); 211 wdev_unlock(wdev); 212 } 213 EXPORT_SYMBOL(cfg80211_send_deauth); 214 215 void __cfg80211_send_disassoc(struct net_device *dev, 216 const u8 *buf, size_t len) 217 { 218 struct wireless_dev *wdev = dev->ieee80211_ptr; 219 struct wiphy *wiphy = wdev->wiphy; 220 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 221 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 222 const u8 *bssid = mgmt->bssid; 223 int i; 224 u16 reason_code; 225 bool from_ap; 226 bool done = false; 227 228 ASSERT_WDEV_LOCK(wdev); 229 230 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 231 232 if (wdev->sme_state != CFG80211_SME_CONNECTED) 233 return; 234 235 if (wdev->current_bss && 236 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 237 for (i = 0; i < MAX_AUTH_BSSES; i++) { 238 if (wdev->authtry_bsses[i] || wdev->auth_bsses[i]) 239 continue; 240 wdev->auth_bsses[i] = wdev->current_bss; 241 wdev->current_bss = NULL; 242 done = true; 243 cfg80211_sme_disassoc(dev, i); 244 break; 245 } 246 WARN_ON(!done); 247 } else 248 WARN_ON(1); 249 250 251 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 252 253 from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0; 254 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 255 } 256 EXPORT_SYMBOL(__cfg80211_send_disassoc); 257 258 void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) 259 { 260 struct wireless_dev *wdev = dev->ieee80211_ptr; 261 262 wdev_lock(wdev); 263 __cfg80211_send_disassoc(dev, buf, len); 264 wdev_unlock(wdev); 265 } 266 EXPORT_SYMBOL(cfg80211_send_disassoc); 267 268 void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, 269 size_t len) 270 { 271 struct wireless_dev *wdev = dev->ieee80211_ptr; 272 struct wiphy *wiphy = wdev->wiphy; 273 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 274 275 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC); 276 } 277 EXPORT_SYMBOL(cfg80211_send_unprot_deauth); 278 279 void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, 280 size_t len) 281 { 282 struct wireless_dev *wdev = dev->ieee80211_ptr; 283 struct wiphy *wiphy = wdev->wiphy; 284 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 285 286 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC); 287 } 288 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); 289 290 static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) 291 { 292 int i; 293 bool done = false; 294 295 ASSERT_WDEV_LOCK(wdev); 296 297 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 298 if (wdev->authtry_bsses[i] && 299 memcmp(wdev->authtry_bsses[i]->pub.bssid, 300 addr, ETH_ALEN) == 0) { 301 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 302 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 303 wdev->authtry_bsses[i] = NULL; 304 done = true; 305 break; 306 } 307 } 308 309 WARN_ON(!done); 310 } 311 312 void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr) 313 { 314 __cfg80211_auth_remove(dev->ieee80211_ptr, addr); 315 } 316 EXPORT_SYMBOL(__cfg80211_auth_canceled); 317 318 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 319 { 320 struct wireless_dev *wdev = dev->ieee80211_ptr; 321 struct wiphy *wiphy = wdev->wiphy; 322 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 323 324 wdev_lock(wdev); 325 326 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 327 if (wdev->sme_state == CFG80211_SME_CONNECTING) 328 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 329 WLAN_STATUS_UNSPECIFIED_FAILURE, 330 false, NULL); 331 332 __cfg80211_auth_remove(wdev, addr); 333 334 wdev_unlock(wdev); 335 } 336 EXPORT_SYMBOL(cfg80211_send_auth_timeout); 337 338 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) 339 { 340 struct wireless_dev *wdev = dev->ieee80211_ptr; 341 struct wiphy *wiphy = wdev->wiphy; 342 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 343 int i; 344 bool done = false; 345 346 wdev_lock(wdev); 347 348 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 349 if (wdev->sme_state == CFG80211_SME_CONNECTING) 350 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 351 WLAN_STATUS_UNSPECIFIED_FAILURE, 352 false, NULL); 353 354 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 355 if (wdev->auth_bsses[i] && 356 memcmp(wdev->auth_bsses[i]->pub.bssid, 357 addr, ETH_ALEN) == 0) { 358 cfg80211_unhold_bss(wdev->auth_bsses[i]); 359 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 360 wdev->auth_bsses[i] = NULL; 361 done = true; 362 break; 363 } 364 } 365 366 WARN_ON(!done); 367 368 wdev_unlock(wdev); 369 } 370 EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 371 372 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, 373 enum nl80211_key_type key_type, int key_id, 374 const u8 *tsc, gfp_t gfp) 375 { 376 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 377 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 378 #ifdef CONFIG_CFG80211_WEXT 379 union iwreq_data wrqu; 380 char *buf = kmalloc(128, gfp); 381 382 if (buf) { 383 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" 384 "keyid=%d %scast addr=%pM)", key_id, 385 key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni", 386 addr); 387 memset(&wrqu, 0, sizeof(wrqu)); 388 wrqu.data.length = strlen(buf); 389 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); 390 kfree(buf); 391 } 392 #endif 393 394 nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp); 395 } 396 EXPORT_SYMBOL(cfg80211_michael_mic_failure); 397 398 /* some MLME handling for userspace SME */ 399 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 400 struct net_device *dev, 401 struct ieee80211_channel *chan, 402 enum nl80211_auth_type auth_type, 403 const u8 *bssid, 404 const u8 *ssid, int ssid_len, 405 const u8 *ie, int ie_len, 406 const u8 *key, int key_len, int key_idx, 407 bool local_state_change) 408 { 409 struct wireless_dev *wdev = dev->ieee80211_ptr; 410 struct cfg80211_auth_request req; 411 struct cfg80211_internal_bss *bss; 412 int i, err, slot = -1, nfree = 0; 413 414 ASSERT_WDEV_LOCK(wdev); 415 416 if (auth_type == NL80211_AUTHTYPE_SHARED_KEY) 417 if (!key || !key_len || key_idx < 0 || key_idx > 4) 418 return -EINVAL; 419 420 if (wdev->current_bss && 421 memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0) 422 return -EALREADY; 423 424 for (i = 0; i < MAX_AUTH_BSSES; i++) { 425 if (wdev->authtry_bsses[i] && 426 memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, 427 ETH_ALEN) == 0) 428 return -EALREADY; 429 if (wdev->auth_bsses[i] && 430 memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, 431 ETH_ALEN) == 0) 432 return -EALREADY; 433 } 434 435 memset(&req, 0, sizeof(req)); 436 437 req.local_state_change = local_state_change; 438 req.ie = ie; 439 req.ie_len = ie_len; 440 req.auth_type = auth_type; 441 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 442 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 443 req.key = key; 444 req.key_len = key_len; 445 req.key_idx = key_idx; 446 if (!req.bss) 447 return -ENOENT; 448 449 bss = bss_from_pub(req.bss); 450 451 for (i = 0; i < MAX_AUTH_BSSES; i++) { 452 if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) { 453 slot = i; 454 nfree++; 455 } 456 } 457 458 /* we need one free slot for disassoc and one for this auth */ 459 if (nfree < 2) { 460 err = -ENOSPC; 461 goto out; 462 } 463 464 if (local_state_change) 465 wdev->auth_bsses[slot] = bss; 466 else 467 wdev->authtry_bsses[slot] = bss; 468 cfg80211_hold_bss(bss); 469 470 err = rdev->ops->auth(&rdev->wiphy, dev, &req); 471 if (err) { 472 if (local_state_change) 473 wdev->auth_bsses[slot] = NULL; 474 else 475 wdev->authtry_bsses[slot] = NULL; 476 cfg80211_unhold_bss(bss); 477 } 478 479 out: 480 if (err) 481 cfg80211_put_bss(req.bss); 482 return err; 483 } 484 485 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 486 struct net_device *dev, struct ieee80211_channel *chan, 487 enum nl80211_auth_type auth_type, const u8 *bssid, 488 const u8 *ssid, int ssid_len, 489 const u8 *ie, int ie_len, 490 const u8 *key, int key_len, int key_idx, 491 bool local_state_change) 492 { 493 int err; 494 495 wdev_lock(dev->ieee80211_ptr); 496 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 497 ssid, ssid_len, ie, ie_len, 498 key, key_len, key_idx, local_state_change); 499 wdev_unlock(dev->ieee80211_ptr); 500 501 return err; 502 } 503 504 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 505 struct net_device *dev, 506 struct ieee80211_channel *chan, 507 const u8 *bssid, const u8 *prev_bssid, 508 const u8 *ssid, int ssid_len, 509 const u8 *ie, int ie_len, bool use_mfp, 510 struct cfg80211_crypto_settings *crypt) 511 { 512 struct wireless_dev *wdev = dev->ieee80211_ptr; 513 struct cfg80211_assoc_request req; 514 struct cfg80211_internal_bss *bss; 515 int i, err, slot = -1; 516 bool was_connected = false; 517 518 ASSERT_WDEV_LOCK(wdev); 519 520 memset(&req, 0, sizeof(req)); 521 522 if (wdev->current_bss && prev_bssid && 523 memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) { 524 /* 525 * Trying to reassociate: Allow this to proceed and let the old 526 * association to be dropped when the new one is completed. 527 */ 528 if (wdev->sme_state == CFG80211_SME_CONNECTED) { 529 was_connected = true; 530 wdev->sme_state = CFG80211_SME_CONNECTING; 531 } 532 } else if (wdev->current_bss) 533 return -EALREADY; 534 535 req.ie = ie; 536 req.ie_len = ie_len; 537 memcpy(&req.crypto, crypt, sizeof(req.crypto)); 538 req.use_mfp = use_mfp; 539 req.prev_bssid = prev_bssid; 540 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 541 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 542 if (!req.bss) { 543 if (was_connected) 544 wdev->sme_state = CFG80211_SME_CONNECTED; 545 return -ENOENT; 546 } 547 548 bss = bss_from_pub(req.bss); 549 550 for (i = 0; i < MAX_AUTH_BSSES; i++) { 551 if (bss == wdev->auth_bsses[i]) { 552 slot = i; 553 break; 554 } 555 } 556 557 if (slot < 0) { 558 err = -ENOTCONN; 559 goto out; 560 } 561 562 err = rdev->ops->assoc(&rdev->wiphy, dev, &req); 563 out: 564 if (err && was_connected) 565 wdev->sme_state = CFG80211_SME_CONNECTED; 566 /* still a reference in wdev->auth_bsses[slot] */ 567 cfg80211_put_bss(req.bss); 568 return err; 569 } 570 571 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 572 struct net_device *dev, 573 struct ieee80211_channel *chan, 574 const u8 *bssid, const u8 *prev_bssid, 575 const u8 *ssid, int ssid_len, 576 const u8 *ie, int ie_len, bool use_mfp, 577 struct cfg80211_crypto_settings *crypt) 578 { 579 struct wireless_dev *wdev = dev->ieee80211_ptr; 580 int err; 581 582 wdev_lock(wdev); 583 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 584 ssid, ssid_len, ie, ie_len, use_mfp, crypt); 585 wdev_unlock(wdev); 586 587 return err; 588 } 589 590 int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 591 struct net_device *dev, const u8 *bssid, 592 const u8 *ie, int ie_len, u16 reason, 593 bool local_state_change) 594 { 595 struct wireless_dev *wdev = dev->ieee80211_ptr; 596 struct cfg80211_deauth_request req; 597 int i; 598 599 ASSERT_WDEV_LOCK(wdev); 600 601 memset(&req, 0, sizeof(req)); 602 req.reason_code = reason; 603 req.local_state_change = local_state_change; 604 req.ie = ie; 605 req.ie_len = ie_len; 606 if (wdev->current_bss && 607 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 608 req.bss = &wdev->current_bss->pub; 609 } else for (i = 0; i < MAX_AUTH_BSSES; i++) { 610 if (wdev->auth_bsses[i] && 611 memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) { 612 req.bss = &wdev->auth_bsses[i]->pub; 613 break; 614 } 615 if (wdev->authtry_bsses[i] && 616 memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) { 617 req.bss = &wdev->authtry_bsses[i]->pub; 618 break; 619 } 620 } 621 622 if (!req.bss) 623 return -ENOTCONN; 624 625 return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev); 626 } 627 628 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 629 struct net_device *dev, const u8 *bssid, 630 const u8 *ie, int ie_len, u16 reason, 631 bool local_state_change) 632 { 633 struct wireless_dev *wdev = dev->ieee80211_ptr; 634 int err; 635 636 wdev_lock(wdev); 637 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason, 638 local_state_change); 639 wdev_unlock(wdev); 640 641 return err; 642 } 643 644 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 645 struct net_device *dev, const u8 *bssid, 646 const u8 *ie, int ie_len, u16 reason, 647 bool local_state_change) 648 { 649 struct wireless_dev *wdev = dev->ieee80211_ptr; 650 struct cfg80211_disassoc_request req; 651 652 ASSERT_WDEV_LOCK(wdev); 653 654 if (wdev->sme_state != CFG80211_SME_CONNECTED) 655 return -ENOTCONN; 656 657 if (WARN_ON(!wdev->current_bss)) 658 return -ENOTCONN; 659 660 memset(&req, 0, sizeof(req)); 661 req.reason_code = reason; 662 req.local_state_change = local_state_change; 663 req.ie = ie; 664 req.ie_len = ie_len; 665 if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) 666 req.bss = &wdev->current_bss->pub; 667 else 668 return -ENOTCONN; 669 670 return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev); 671 } 672 673 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 674 struct net_device *dev, const u8 *bssid, 675 const u8 *ie, int ie_len, u16 reason, 676 bool local_state_change) 677 { 678 struct wireless_dev *wdev = dev->ieee80211_ptr; 679 int err; 680 681 wdev_lock(wdev); 682 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason, 683 local_state_change); 684 wdev_unlock(wdev); 685 686 return err; 687 } 688 689 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 690 struct net_device *dev) 691 { 692 struct wireless_dev *wdev = dev->ieee80211_ptr; 693 struct cfg80211_deauth_request req; 694 int i; 695 696 ASSERT_WDEV_LOCK(wdev); 697 698 if (!rdev->ops->deauth) 699 return; 700 701 memset(&req, 0, sizeof(req)); 702 req.reason_code = WLAN_REASON_DEAUTH_LEAVING; 703 req.ie = NULL; 704 req.ie_len = 0; 705 706 if (wdev->current_bss) { 707 req.bss = &wdev->current_bss->pub; 708 rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev); 709 if (wdev->current_bss) { 710 cfg80211_unhold_bss(wdev->current_bss); 711 cfg80211_put_bss(&wdev->current_bss->pub); 712 wdev->current_bss = NULL; 713 } 714 } 715 716 for (i = 0; i < MAX_AUTH_BSSES; i++) { 717 if (wdev->auth_bsses[i]) { 718 req.bss = &wdev->auth_bsses[i]->pub; 719 rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev); 720 if (wdev->auth_bsses[i]) { 721 cfg80211_unhold_bss(wdev->auth_bsses[i]); 722 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 723 wdev->auth_bsses[i] = NULL; 724 } 725 } 726 if (wdev->authtry_bsses[i]) { 727 req.bss = &wdev->authtry_bsses[i]->pub; 728 rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev); 729 if (wdev->authtry_bsses[i]) { 730 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 731 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 732 wdev->authtry_bsses[i] = NULL; 733 } 734 } 735 } 736 } 737 738 void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie, 739 struct ieee80211_channel *chan, 740 enum nl80211_channel_type channel_type, 741 unsigned int duration, gfp_t gfp) 742 { 743 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 744 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 745 746 nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type, 747 duration, gfp); 748 } 749 EXPORT_SYMBOL(cfg80211_ready_on_channel); 750 751 void cfg80211_remain_on_channel_expired(struct net_device *dev, 752 u64 cookie, 753 struct ieee80211_channel *chan, 754 enum nl80211_channel_type channel_type, 755 gfp_t gfp) 756 { 757 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 758 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 759 760 nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan, 761 channel_type, gfp); 762 } 763 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); 764 765 void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, 766 struct station_info *sinfo, gfp_t gfp) 767 { 768 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 769 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 770 771 nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp); 772 } 773 EXPORT_SYMBOL(cfg80211_new_sta); 774 775 void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) 776 { 777 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 778 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 779 780 nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); 781 } 782 EXPORT_SYMBOL(cfg80211_del_sta); 783 784 struct cfg80211_mgmt_registration { 785 struct list_head list; 786 787 u32 nlpid; 788 789 int match_len; 790 791 __le16 frame_type; 792 793 u8 match[]; 794 }; 795 796 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 797 u16 frame_type, const u8 *match_data, 798 int match_len) 799 { 800 struct wiphy *wiphy = wdev->wiphy; 801 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 802 struct cfg80211_mgmt_registration *reg, *nreg; 803 int err = 0; 804 u16 mgmt_type; 805 806 if (!wdev->wiphy->mgmt_stypes) 807 return -EOPNOTSUPP; 808 809 if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) 810 return -EINVAL; 811 812 if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) 813 return -EINVAL; 814 815 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; 816 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) 817 return -EINVAL; 818 819 nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL); 820 if (!nreg) 821 return -ENOMEM; 822 823 spin_lock_bh(&wdev->mgmt_registrations_lock); 824 825 list_for_each_entry(reg, &wdev->mgmt_registrations, list) { 826 int mlen = min(match_len, reg->match_len); 827 828 if (frame_type != le16_to_cpu(reg->frame_type)) 829 continue; 830 831 if (memcmp(reg->match, match_data, mlen) == 0) { 832 err = -EALREADY; 833 break; 834 } 835 } 836 837 if (err) { 838 kfree(nreg); 839 goto out; 840 } 841 842 memcpy(nreg->match, match_data, match_len); 843 nreg->match_len = match_len; 844 nreg->nlpid = snd_pid; 845 nreg->frame_type = cpu_to_le16(frame_type); 846 list_add(&nreg->list, &wdev->mgmt_registrations); 847 848 if (rdev->ops->mgmt_frame_register) 849 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, 850 frame_type, true); 851 852 out: 853 spin_unlock_bh(&wdev->mgmt_registrations_lock); 854 855 return err; 856 } 857 858 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 859 { 860 struct wiphy *wiphy = wdev->wiphy; 861 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 862 struct cfg80211_mgmt_registration *reg, *tmp; 863 864 spin_lock_bh(&wdev->mgmt_registrations_lock); 865 866 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 867 if (reg->nlpid != nlpid) 868 continue; 869 870 if (rdev->ops->mgmt_frame_register) { 871 u16 frame_type = le16_to_cpu(reg->frame_type); 872 873 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, 874 frame_type, false); 875 } 876 877 list_del(®->list); 878 kfree(reg); 879 } 880 881 spin_unlock_bh(&wdev->mgmt_registrations_lock); 882 } 883 884 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) 885 { 886 struct cfg80211_mgmt_registration *reg, *tmp; 887 888 spin_lock_bh(&wdev->mgmt_registrations_lock); 889 890 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 891 list_del(®->list); 892 kfree(reg); 893 } 894 895 spin_unlock_bh(&wdev->mgmt_registrations_lock); 896 } 897 898 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 899 struct net_device *dev, 900 struct ieee80211_channel *chan, bool offchan, 901 enum nl80211_channel_type channel_type, 902 bool channel_type_valid, unsigned int wait, 903 const u8 *buf, size_t len, u64 *cookie) 904 { 905 struct wireless_dev *wdev = dev->ieee80211_ptr; 906 const struct ieee80211_mgmt *mgmt; 907 u16 stype; 908 909 if (!wdev->wiphy->mgmt_stypes) 910 return -EOPNOTSUPP; 911 912 if (!rdev->ops->mgmt_tx) 913 return -EOPNOTSUPP; 914 915 if (len < 24 + 1) 916 return -EINVAL; 917 918 mgmt = (const struct ieee80211_mgmt *) buf; 919 920 if (!ieee80211_is_mgmt(mgmt->frame_control)) 921 return -EINVAL; 922 923 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 924 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4))) 925 return -EINVAL; 926 927 if (ieee80211_is_action(mgmt->frame_control) && 928 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { 929 int err = 0; 930 931 wdev_lock(wdev); 932 933 switch (wdev->iftype) { 934 case NL80211_IFTYPE_ADHOC: 935 case NL80211_IFTYPE_STATION: 936 case NL80211_IFTYPE_P2P_CLIENT: 937 if (!wdev->current_bss) { 938 err = -ENOTCONN; 939 break; 940 } 941 942 if (memcmp(wdev->current_bss->pub.bssid, 943 mgmt->bssid, ETH_ALEN)) { 944 err = -ENOTCONN; 945 break; 946 } 947 948 /* 949 * check for IBSS DA must be done by driver as 950 * cfg80211 doesn't track the stations 951 */ 952 if (wdev->iftype == NL80211_IFTYPE_ADHOC) 953 break; 954 955 /* for station, check that DA is the AP */ 956 if (memcmp(wdev->current_bss->pub.bssid, 957 mgmt->da, ETH_ALEN)) { 958 err = -ENOTCONN; 959 break; 960 } 961 break; 962 case NL80211_IFTYPE_AP: 963 case NL80211_IFTYPE_P2P_GO: 964 case NL80211_IFTYPE_AP_VLAN: 965 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) 966 err = -EINVAL; 967 break; 968 case NL80211_IFTYPE_MESH_POINT: 969 if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) { 970 err = -EINVAL; 971 break; 972 } 973 /* 974 * check for mesh DA must be done by driver as 975 * cfg80211 doesn't track the stations 976 */ 977 break; 978 default: 979 err = -EOPNOTSUPP; 980 break; 981 } 982 wdev_unlock(wdev); 983 984 if (err) 985 return err; 986 } 987 988 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 989 return -EINVAL; 990 991 /* Transmit the Action frame as requested by user space */ 992 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, 993 channel_type, channel_type_valid, 994 wait, buf, len, cookie); 995 } 996 997 bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, 998 size_t len, gfp_t gfp) 999 { 1000 struct wireless_dev *wdev = dev->ieee80211_ptr; 1001 struct wiphy *wiphy = wdev->wiphy; 1002 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1003 struct cfg80211_mgmt_registration *reg; 1004 const struct ieee80211_txrx_stypes *stypes = 1005 &wiphy->mgmt_stypes[wdev->iftype]; 1006 struct ieee80211_mgmt *mgmt = (void *)buf; 1007 const u8 *data; 1008 int data_len; 1009 bool result = false; 1010 __le16 ftype = mgmt->frame_control & 1011 cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); 1012 u16 stype; 1013 1014 stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; 1015 1016 if (!(stypes->rx & BIT(stype))) 1017 return false; 1018 1019 data = buf + ieee80211_hdrlen(mgmt->frame_control); 1020 data_len = len - ieee80211_hdrlen(mgmt->frame_control); 1021 1022 spin_lock_bh(&wdev->mgmt_registrations_lock); 1023 1024 list_for_each_entry(reg, &wdev->mgmt_registrations, list) { 1025 if (reg->frame_type != ftype) 1026 continue; 1027 1028 if (reg->match_len > data_len) 1029 continue; 1030 1031 if (memcmp(reg->match, data, reg->match_len)) 1032 continue; 1033 1034 /* found match! */ 1035 1036 /* Indicate the received Action frame to user space */ 1037 if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, 1038 buf, len, gfp)) 1039 continue; 1040 1041 result = true; 1042 break; 1043 } 1044 1045 spin_unlock_bh(&wdev->mgmt_registrations_lock); 1046 1047 return result; 1048 } 1049 EXPORT_SYMBOL(cfg80211_rx_mgmt); 1050 1051 void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, 1052 const u8 *buf, size_t len, bool ack, gfp_t gfp) 1053 { 1054 struct wireless_dev *wdev = dev->ieee80211_ptr; 1055 struct wiphy *wiphy = wdev->wiphy; 1056 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1057 1058 /* Indicate TX status of the Action frame to user space */ 1059 nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp); 1060 } 1061 EXPORT_SYMBOL(cfg80211_mgmt_tx_status); 1062 1063 void cfg80211_cqm_rssi_notify(struct net_device *dev, 1064 enum nl80211_cqm_rssi_threshold_event rssi_event, 1065 gfp_t gfp) 1066 { 1067 struct wireless_dev *wdev = dev->ieee80211_ptr; 1068 struct wiphy *wiphy = wdev->wiphy; 1069 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1070 1071 /* Indicate roaming trigger event to user space */ 1072 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); 1073 } 1074 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); 1075 1076 void cfg80211_cqm_pktloss_notify(struct net_device *dev, 1077 const u8 *peer, u32 num_packets, gfp_t gfp) 1078 { 1079 struct wireless_dev *wdev = dev->ieee80211_ptr; 1080 struct wiphy *wiphy = wdev->wiphy; 1081 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1082 1083 /* Indicate roaming trigger event to user space */ 1084 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); 1085 } 1086 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); 1087