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