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 void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) 774 { 775 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 776 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 777 778 nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); 779 } 780 EXPORT_SYMBOL(cfg80211_del_sta); 781 782 struct cfg80211_mgmt_registration { 783 struct list_head list; 784 785 u32 nlpid; 786 787 int match_len; 788 789 __le16 frame_type; 790 791 u8 match[]; 792 }; 793 794 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 795 u16 frame_type, const u8 *match_data, 796 int match_len) 797 { 798 struct wiphy *wiphy = wdev->wiphy; 799 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 800 struct cfg80211_mgmt_registration *reg, *nreg; 801 int err = 0; 802 u16 mgmt_type; 803 804 if (!wdev->wiphy->mgmt_stypes) 805 return -EOPNOTSUPP; 806 807 if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) 808 return -EINVAL; 809 810 if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) 811 return -EINVAL; 812 813 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; 814 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) 815 return -EINVAL; 816 817 nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL); 818 if (!nreg) 819 return -ENOMEM; 820 821 spin_lock_bh(&wdev->mgmt_registrations_lock); 822 823 list_for_each_entry(reg, &wdev->mgmt_registrations, list) { 824 int mlen = min(match_len, reg->match_len); 825 826 if (frame_type != le16_to_cpu(reg->frame_type)) 827 continue; 828 829 if (memcmp(reg->match, match_data, mlen) == 0) { 830 err = -EALREADY; 831 break; 832 } 833 } 834 835 if (err) { 836 kfree(nreg); 837 goto out; 838 } 839 840 memcpy(nreg->match, match_data, match_len); 841 nreg->match_len = match_len; 842 nreg->nlpid = snd_pid; 843 nreg->frame_type = cpu_to_le16(frame_type); 844 list_add(&nreg->list, &wdev->mgmt_registrations); 845 846 if (rdev->ops->mgmt_frame_register) 847 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, 848 frame_type, true); 849 850 out: 851 spin_unlock_bh(&wdev->mgmt_registrations_lock); 852 853 return err; 854 } 855 856 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 857 { 858 struct wiphy *wiphy = wdev->wiphy; 859 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 860 struct cfg80211_mgmt_registration *reg, *tmp; 861 862 spin_lock_bh(&wdev->mgmt_registrations_lock); 863 864 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 865 if (reg->nlpid != nlpid) 866 continue; 867 868 if (rdev->ops->mgmt_frame_register) { 869 u16 frame_type = le16_to_cpu(reg->frame_type); 870 871 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, 872 frame_type, false); 873 } 874 875 list_del(®->list); 876 kfree(reg); 877 } 878 879 spin_unlock_bh(&wdev->mgmt_registrations_lock); 880 } 881 882 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) 883 { 884 struct cfg80211_mgmt_registration *reg, *tmp; 885 886 spin_lock_bh(&wdev->mgmt_registrations_lock); 887 888 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 889 list_del(®->list); 890 kfree(reg); 891 } 892 893 spin_unlock_bh(&wdev->mgmt_registrations_lock); 894 } 895 896 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 897 struct net_device *dev, 898 struct ieee80211_channel *chan, bool offchan, 899 enum nl80211_channel_type channel_type, 900 bool channel_type_valid, unsigned int wait, 901 const u8 *buf, size_t len, u64 *cookie) 902 { 903 struct wireless_dev *wdev = dev->ieee80211_ptr; 904 const struct ieee80211_mgmt *mgmt; 905 u16 stype; 906 907 if (!wdev->wiphy->mgmt_stypes) 908 return -EOPNOTSUPP; 909 910 if (!rdev->ops->mgmt_tx) 911 return -EOPNOTSUPP; 912 913 if (len < 24 + 1) 914 return -EINVAL; 915 916 mgmt = (const struct ieee80211_mgmt *) buf; 917 918 if (!ieee80211_is_mgmt(mgmt->frame_control)) 919 return -EINVAL; 920 921 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 922 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4))) 923 return -EINVAL; 924 925 if (ieee80211_is_action(mgmt->frame_control) && 926 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { 927 int err = 0; 928 929 wdev_lock(wdev); 930 931 switch (wdev->iftype) { 932 case NL80211_IFTYPE_ADHOC: 933 case NL80211_IFTYPE_STATION: 934 case NL80211_IFTYPE_P2P_CLIENT: 935 if (!wdev->current_bss) { 936 err = -ENOTCONN; 937 break; 938 } 939 940 if (memcmp(wdev->current_bss->pub.bssid, 941 mgmt->bssid, ETH_ALEN)) { 942 err = -ENOTCONN; 943 break; 944 } 945 946 /* 947 * check for IBSS DA must be done by driver as 948 * cfg80211 doesn't track the stations 949 */ 950 if (wdev->iftype == NL80211_IFTYPE_ADHOC) 951 break; 952 953 /* for station, check that DA is the AP */ 954 if (memcmp(wdev->current_bss->pub.bssid, 955 mgmt->da, ETH_ALEN)) { 956 err = -ENOTCONN; 957 break; 958 } 959 break; 960 case NL80211_IFTYPE_AP: 961 case NL80211_IFTYPE_P2P_GO: 962 case NL80211_IFTYPE_AP_VLAN: 963 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) 964 err = -EINVAL; 965 break; 966 case NL80211_IFTYPE_MESH_POINT: 967 if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) { 968 err = -EINVAL; 969 break; 970 } 971 /* 972 * check for mesh DA must be done by driver as 973 * cfg80211 doesn't track the stations 974 */ 975 break; 976 default: 977 err = -EOPNOTSUPP; 978 break; 979 } 980 wdev_unlock(wdev); 981 982 if (err) 983 return err; 984 } 985 986 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 987 return -EINVAL; 988 989 /* Transmit the Action frame as requested by user space */ 990 return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, 991 channel_type, channel_type_valid, 992 wait, buf, len, cookie); 993 } 994 995 bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, 996 size_t len, gfp_t gfp) 997 { 998 struct wireless_dev *wdev = dev->ieee80211_ptr; 999 struct wiphy *wiphy = wdev->wiphy; 1000 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1001 struct cfg80211_mgmt_registration *reg; 1002 const struct ieee80211_txrx_stypes *stypes = 1003 &wiphy->mgmt_stypes[wdev->iftype]; 1004 struct ieee80211_mgmt *mgmt = (void *)buf; 1005 const u8 *data; 1006 int data_len; 1007 bool result = false; 1008 __le16 ftype = mgmt->frame_control & 1009 cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); 1010 u16 stype; 1011 1012 stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; 1013 1014 if (!(stypes->rx & BIT(stype))) 1015 return false; 1016 1017 data = buf + ieee80211_hdrlen(mgmt->frame_control); 1018 data_len = len - ieee80211_hdrlen(mgmt->frame_control); 1019 1020 spin_lock_bh(&wdev->mgmt_registrations_lock); 1021 1022 list_for_each_entry(reg, &wdev->mgmt_registrations, list) { 1023 if (reg->frame_type != ftype) 1024 continue; 1025 1026 if (reg->match_len > data_len) 1027 continue; 1028 1029 if (memcmp(reg->match, data, reg->match_len)) 1030 continue; 1031 1032 /* found match! */ 1033 1034 /* Indicate the received Action frame to user space */ 1035 if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, 1036 buf, len, gfp)) 1037 continue; 1038 1039 result = true; 1040 break; 1041 } 1042 1043 spin_unlock_bh(&wdev->mgmt_registrations_lock); 1044 1045 return result; 1046 } 1047 EXPORT_SYMBOL(cfg80211_rx_mgmt); 1048 1049 void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, 1050 const u8 *buf, size_t len, bool ack, gfp_t gfp) 1051 { 1052 struct wireless_dev *wdev = dev->ieee80211_ptr; 1053 struct wiphy *wiphy = wdev->wiphy; 1054 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1055 1056 /* Indicate TX status of the Action frame to user space */ 1057 nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp); 1058 } 1059 EXPORT_SYMBOL(cfg80211_mgmt_tx_status); 1060 1061 void cfg80211_cqm_rssi_notify(struct net_device *dev, 1062 enum nl80211_cqm_rssi_threshold_event rssi_event, 1063 gfp_t gfp) 1064 { 1065 struct wireless_dev *wdev = dev->ieee80211_ptr; 1066 struct wiphy *wiphy = wdev->wiphy; 1067 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1068 1069 /* Indicate roaming trigger event to user space */ 1070 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); 1071 } 1072 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); 1073 1074 void cfg80211_cqm_pktloss_notify(struct net_device *dev, 1075 const u8 *peer, u32 num_packets, gfp_t gfp) 1076 { 1077 struct wireless_dev *wdev = dev->ieee80211_ptr; 1078 struct wiphy *wiphy = wdev->wiphy; 1079 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1080 1081 /* Indicate roaming trigger event to user space */ 1082 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); 1083 } 1084 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); 1085