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