linux/net/wireless/mlme.c
<<
>>
Prefs
   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/etherdevice.h>
  10#include <linux/netdevice.h>
  11#include <linux/nl80211.h>
  12#include <linux/slab.h>
  13#include <linux/wireless.h>
  14#include <net/cfg80211.h>
  15#include <net/iw_handler.h>
  16#include "core.h"
  17#include "nl80211.h"
  18#include "rdev-ops.h"
  19
  20
  21void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
  22{
  23        struct wireless_dev *wdev = dev->ieee80211_ptr;
  24        struct wiphy *wiphy = wdev->wiphy;
  25        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  26
  27        trace_cfg80211_send_rx_auth(dev);
  28        wdev_lock(wdev);
  29
  30        nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
  31        cfg80211_sme_rx_auth(dev, buf, len);
  32
  33        wdev_unlock(wdev);
  34}
  35EXPORT_SYMBOL(cfg80211_send_rx_auth);
  36
  37void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
  38                            const u8 *buf, size_t len)
  39{
  40        u16 status_code;
  41        struct wireless_dev *wdev = dev->ieee80211_ptr;
  42        struct wiphy *wiphy = wdev->wiphy;
  43        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  44        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  45        u8 *ie = mgmt->u.assoc_resp.variable;
  46        int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
  47
  48        trace_cfg80211_send_rx_assoc(dev, bss);
  49        wdev_lock(wdev);
  50
  51        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
  52
  53        /*
  54         * This is a bit of a hack, we don't notify userspace of
  55         * a (re-)association reply if we tried to send a reassoc
  56         * and got a reject -- we only try again with an assoc
  57         * frame instead of reassoc.
  58         */
  59        if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
  60            cfg80211_sme_failed_reassoc(wdev)) {
  61                cfg80211_put_bss(wiphy, bss);
  62                goto out;
  63        }
  64
  65        nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
  66
  67        if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
  68                cfg80211_sme_failed_assoc(wdev);
  69                /*
  70                 * do not call connect_result() now because the
  71                 * sme will schedule work that does it later.
  72                 */
  73                cfg80211_put_bss(wiphy, bss);
  74                goto out;
  75        }
  76
  77        if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
  78                /*
  79                 * This is for the userspace SME, the CONNECTING
  80                 * state will be changed to CONNECTED by
  81                 * __cfg80211_connect_result() below.
  82                 */
  83                wdev->sme_state = CFG80211_SME_CONNECTING;
  84        }
  85
  86        /* this consumes the bss reference */
  87        __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
  88                                  status_code,
  89                                  status_code == WLAN_STATUS_SUCCESS, bss);
  90 out:
  91        wdev_unlock(wdev);
  92}
  93EXPORT_SYMBOL(cfg80211_send_rx_assoc);
  94
  95void __cfg80211_send_deauth(struct net_device *dev,
  96                                   const u8 *buf, size_t len)
  97{
  98        struct wireless_dev *wdev = dev->ieee80211_ptr;
  99        struct wiphy *wiphy = wdev->wiphy;
 100        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 101        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 102        const u8 *bssid = mgmt->bssid;
 103        bool was_current = false;
 104
 105        trace___cfg80211_send_deauth(dev);
 106        ASSERT_WDEV_LOCK(wdev);
 107
 108        if (wdev->current_bss &&
 109            ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
 110                cfg80211_unhold_bss(wdev->current_bss);
 111                cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
 112                wdev->current_bss = NULL;
 113                was_current = true;
 114        }
 115
 116        nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 117
 118        if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
 119                u16 reason_code;
 120                bool from_ap;
 121
 122                reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 123
 124                from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
 125                __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 126        } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
 127                __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
 128                                          WLAN_STATUS_UNSPECIFIED_FAILURE,
 129                                          false, NULL);
 130        }
 131}
 132EXPORT_SYMBOL(__cfg80211_send_deauth);
 133
 134void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
 135{
 136        struct wireless_dev *wdev = dev->ieee80211_ptr;
 137
 138        wdev_lock(wdev);
 139        __cfg80211_send_deauth(dev, buf, len);
 140        wdev_unlock(wdev);
 141}
 142EXPORT_SYMBOL(cfg80211_send_deauth);
 143
 144void __cfg80211_send_disassoc(struct net_device *dev,
 145                                     const u8 *buf, size_t len)
 146{
 147        struct wireless_dev *wdev = dev->ieee80211_ptr;
 148        struct wiphy *wiphy = wdev->wiphy;
 149        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 150        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 151        const u8 *bssid = mgmt->bssid;
 152        u16 reason_code;
 153        bool from_ap;
 154
 155        trace___cfg80211_send_disassoc(dev);
 156        ASSERT_WDEV_LOCK(wdev);
 157
 158        nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
 159
 160        if (wdev->sme_state != CFG80211_SME_CONNECTED)
 161                return;
 162
 163        if (wdev->current_bss &&
 164            ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
 165                cfg80211_sme_disassoc(dev, wdev->current_bss);
 166                cfg80211_unhold_bss(wdev->current_bss);
 167                cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
 168                wdev->current_bss = NULL;
 169        } else
 170                WARN_ON(1);
 171
 172
 173        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 174
 175        from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
 176        __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 177}
 178EXPORT_SYMBOL(__cfg80211_send_disassoc);
 179
 180void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
 181{
 182        struct wireless_dev *wdev = dev->ieee80211_ptr;
 183
 184        wdev_lock(wdev);
 185        __cfg80211_send_disassoc(dev, buf, len);
 186        wdev_unlock(wdev);
 187}
 188EXPORT_SYMBOL(cfg80211_send_disassoc);
 189
 190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 191{
 192        struct wireless_dev *wdev = dev->ieee80211_ptr;
 193        struct wiphy *wiphy = wdev->wiphy;
 194        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 195
 196        trace_cfg80211_send_auth_timeout(dev, addr);
 197        wdev_lock(wdev);
 198
 199        nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
 200        if (wdev->sme_state == CFG80211_SME_CONNECTING)
 201                __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 202                                          WLAN_STATUS_UNSPECIFIED_FAILURE,
 203                                          false, NULL);
 204
 205        wdev_unlock(wdev);
 206}
 207EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 208
 209void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 210{
 211        struct wireless_dev *wdev = dev->ieee80211_ptr;
 212        struct wiphy *wiphy = wdev->wiphy;
 213        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 214
 215        trace_cfg80211_send_assoc_timeout(dev, addr);
 216        wdev_lock(wdev);
 217
 218        nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
 219        if (wdev->sme_state == CFG80211_SME_CONNECTING)
 220                __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 221                                          WLAN_STATUS_UNSPECIFIED_FAILURE,
 222                                          false, NULL);
 223
 224        wdev_unlock(wdev);
 225}
 226EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 227
 228void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
 229                                  enum nl80211_key_type key_type, int key_id,
 230                                  const u8 *tsc, gfp_t gfp)
 231{
 232        struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 233        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 234#ifdef CONFIG_CFG80211_WEXT
 235        union iwreq_data wrqu;
 236        char *buf = kmalloc(128, gfp);
 237
 238        if (buf) {
 239                sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
 240                        "keyid=%d %scast addr=%pM)", key_id,
 241                        key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
 242                        addr);
 243                memset(&wrqu, 0, sizeof(wrqu));
 244                wrqu.data.length = strlen(buf);
 245                wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
 246                kfree(buf);
 247        }
 248#endif
 249
 250        trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
 251        nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
 252}
 253EXPORT_SYMBOL(cfg80211_michael_mic_failure);
 254
 255/* some MLME handling for userspace SME */
 256int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 257                         struct net_device *dev,
 258                         struct ieee80211_channel *chan,
 259                         enum nl80211_auth_type auth_type,
 260                         const u8 *bssid,
 261                         const u8 *ssid, int ssid_len,
 262                         const u8 *ie, int ie_len,
 263                         const u8 *key, int key_len, int key_idx,
 264                         const u8 *sae_data, int sae_data_len)
 265{
 266        struct wireless_dev *wdev = dev->ieee80211_ptr;
 267        struct cfg80211_auth_request req;
 268        int err;
 269
 270        ASSERT_WDEV_LOCK(wdev);
 271
 272        if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
 273                if (!key || !key_len || key_idx < 0 || key_idx > 4)
 274                        return -EINVAL;
 275
 276        if (wdev->current_bss &&
 277            ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
 278                return -EALREADY;
 279
 280        memset(&req, 0, sizeof(req));
 281
 282        req.ie = ie;
 283        req.ie_len = ie_len;
 284        req.sae_data = sae_data;
 285        req.sae_data_len = sae_data_len;
 286        req.auth_type = auth_type;
 287        req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
 288                                   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 289        req.key = key;
 290        req.key_len = key_len;
 291        req.key_idx = key_idx;
 292        if (!req.bss)
 293                return -ENOENT;
 294
 295        err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
 296                                    CHAN_MODE_SHARED);
 297        if (err)
 298                goto out;
 299
 300        err = rdev_auth(rdev, dev, &req);
 301
 302out:
 303        cfg80211_put_bss(&rdev->wiphy, req.bss);
 304        return err;
 305}
 306
 307int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 308                       struct net_device *dev, struct ieee80211_channel *chan,
 309                       enum nl80211_auth_type auth_type, const u8 *bssid,
 310                       const u8 *ssid, int ssid_len,
 311                       const u8 *ie, int ie_len,
 312                       const u8 *key, int key_len, int key_idx,
 313                       const u8 *sae_data, int sae_data_len)
 314{
 315        int err;
 316
 317        mutex_lock(&rdev->devlist_mtx);
 318        wdev_lock(dev->ieee80211_ptr);
 319        err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
 320                                   ssid, ssid_len, ie, ie_len,
 321                                   key, key_len, key_idx,
 322                                   sae_data, sae_data_len);
 323        wdev_unlock(dev->ieee80211_ptr);
 324        mutex_unlock(&rdev->devlist_mtx);
 325
 326        return err;
 327}
 328
 329/*  Do a logical ht_capa &= ht_capa_mask.  */
 330void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
 331                               const struct ieee80211_ht_cap *ht_capa_mask)
 332{
 333        int i;
 334        u8 *p1, *p2;
 335        if (!ht_capa_mask) {
 336                memset(ht_capa, 0, sizeof(*ht_capa));
 337                return;
 338        }
 339
 340        p1 = (u8*)(ht_capa);
 341        p2 = (u8*)(ht_capa_mask);
 342        for (i = 0; i<sizeof(*ht_capa); i++)
 343                p1[i] &= p2[i];
 344}
 345
 346/*  Do a logical ht_capa &= ht_capa_mask.  */
 347void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
 348                                const struct ieee80211_vht_cap *vht_capa_mask)
 349{
 350        int i;
 351        u8 *p1, *p2;
 352        if (!vht_capa_mask) {
 353                memset(vht_capa, 0, sizeof(*vht_capa));
 354                return;
 355        }
 356
 357        p1 = (u8*)(vht_capa);
 358        p2 = (u8*)(vht_capa_mask);
 359        for (i = 0; i < sizeof(*vht_capa); i++)
 360                p1[i] &= p2[i];
 361}
 362
 363int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 364                          struct net_device *dev,
 365                          struct ieee80211_channel *chan,
 366                          const u8 *bssid,
 367                          const u8 *ssid, int ssid_len,
 368                          struct cfg80211_assoc_request *req)
 369{
 370        struct wireless_dev *wdev = dev->ieee80211_ptr;
 371        int err;
 372        bool was_connected = false;
 373
 374        ASSERT_WDEV_LOCK(wdev);
 375
 376        if (wdev->current_bss && req->prev_bssid &&
 377            ether_addr_equal(wdev->current_bss->pub.bssid, req->prev_bssid)) {
 378                /*
 379                 * Trying to reassociate: Allow this to proceed and let the old
 380                 * association to be dropped when the new one is completed.
 381                 */
 382                if (wdev->sme_state == CFG80211_SME_CONNECTED) {
 383                        was_connected = true;
 384                        wdev->sme_state = CFG80211_SME_CONNECTING;
 385                }
 386        } else if (wdev->current_bss)
 387                return -EALREADY;
 388
 389        cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
 390                                  rdev->wiphy.ht_capa_mod_mask);
 391        cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
 392                                   rdev->wiphy.vht_capa_mod_mask);
 393
 394        req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
 395                                    WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 396        if (!req->bss) {
 397                if (was_connected)
 398                        wdev->sme_state = CFG80211_SME_CONNECTED;
 399                return -ENOENT;
 400        }
 401
 402        err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED);
 403        if (err)
 404                goto out;
 405
 406        err = rdev_assoc(rdev, dev, req);
 407
 408out:
 409        if (err) {
 410                if (was_connected)
 411                        wdev->sme_state = CFG80211_SME_CONNECTED;
 412                cfg80211_put_bss(&rdev->wiphy, req->bss);
 413        }
 414
 415        return err;
 416}
 417
 418int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 419                        struct net_device *dev,
 420                        struct ieee80211_channel *chan,
 421                        const u8 *bssid,
 422                        const u8 *ssid, int ssid_len,
 423                        struct cfg80211_assoc_request *req)
 424{
 425        struct wireless_dev *wdev = dev->ieee80211_ptr;
 426        int err;
 427
 428        mutex_lock(&rdev->devlist_mtx);
 429        wdev_lock(wdev);
 430        err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
 431                                    ssid, ssid_len, req);
 432        wdev_unlock(wdev);
 433        mutex_unlock(&rdev->devlist_mtx);
 434
 435        return err;
 436}
 437
 438int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 439                           struct net_device *dev, const u8 *bssid,
 440                           const u8 *ie, int ie_len, u16 reason,
 441                           bool local_state_change)
 442{
 443        struct wireless_dev *wdev = dev->ieee80211_ptr;
 444        struct cfg80211_deauth_request req = {
 445                .bssid = bssid,
 446                .reason_code = reason,
 447                .ie = ie,
 448                .ie_len = ie_len,
 449                .local_state_change = local_state_change,
 450        };
 451
 452        ASSERT_WDEV_LOCK(wdev);
 453
 454        if (local_state_change && (!wdev->current_bss ||
 455            !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
 456                return 0;
 457
 458        return rdev_deauth(rdev, dev, &req);
 459}
 460
 461int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 462                         struct net_device *dev, const u8 *bssid,
 463                         const u8 *ie, int ie_len, u16 reason,
 464                         bool local_state_change)
 465{
 466        struct wireless_dev *wdev = dev->ieee80211_ptr;
 467        int err;
 468
 469        wdev_lock(wdev);
 470        err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
 471                                     local_state_change);
 472        wdev_unlock(wdev);
 473
 474        return err;
 475}
 476
 477static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
 478                                    struct net_device *dev, const u8 *bssid,
 479                                    const u8 *ie, int ie_len, u16 reason,
 480                                    bool local_state_change)
 481{
 482        struct wireless_dev *wdev = dev->ieee80211_ptr;
 483        struct cfg80211_disassoc_request req;
 484
 485        ASSERT_WDEV_LOCK(wdev);
 486
 487        if (wdev->sme_state != CFG80211_SME_CONNECTED)
 488                return -ENOTCONN;
 489
 490        if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
 491                return -ENOTCONN;
 492
 493        memset(&req, 0, sizeof(req));
 494        req.reason_code = reason;
 495        req.local_state_change = local_state_change;
 496        req.ie = ie;
 497        req.ie_len = ie_len;
 498        if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
 499                req.bss = &wdev->current_bss->pub;
 500        else
 501                return -ENOTCONN;
 502
 503        return rdev_disassoc(rdev, dev, &req);
 504}
 505
 506int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
 507                           struct net_device *dev, const u8 *bssid,
 508                           const u8 *ie, int ie_len, u16 reason,
 509                           bool local_state_change)
 510{
 511        struct wireless_dev *wdev = dev->ieee80211_ptr;
 512        int err;
 513
 514        wdev_lock(wdev);
 515        err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
 516                                       local_state_change);
 517        wdev_unlock(wdev);
 518
 519        return err;
 520}
 521
 522void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 523                        struct net_device *dev)
 524{
 525        struct wireless_dev *wdev = dev->ieee80211_ptr;
 526        struct cfg80211_deauth_request req;
 527        u8 bssid[ETH_ALEN];
 528
 529        ASSERT_WDEV_LOCK(wdev);
 530
 531        if (!rdev->ops->deauth)
 532                return;
 533
 534        memset(&req, 0, sizeof(req));
 535        req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
 536        req.ie = NULL;
 537        req.ie_len = 0;
 538
 539        if (!wdev->current_bss)
 540                return;
 541
 542        memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
 543        req.bssid = bssid;
 544        rdev_deauth(rdev, dev, &req);
 545
 546        if (wdev->current_bss) {
 547                cfg80211_unhold_bss(wdev->current_bss);
 548                cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub);
 549                wdev->current_bss = NULL;
 550        }
 551}
 552
 553struct cfg80211_mgmt_registration {
 554        struct list_head list;
 555
 556        u32 nlportid;
 557
 558        int match_len;
 559
 560        __le16 frame_type;
 561
 562        u8 match[];
 563};
 564
 565int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 566                                u16 frame_type, const u8 *match_data,
 567                                int match_len)
 568{
 569        struct wiphy *wiphy = wdev->wiphy;
 570        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 571        struct cfg80211_mgmt_registration *reg, *nreg;
 572        int err = 0;
 573        u16 mgmt_type;
 574
 575        if (!wdev->wiphy->mgmt_stypes)
 576                return -EOPNOTSUPP;
 577
 578        if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
 579                return -EINVAL;
 580
 581        if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
 582                return -EINVAL;
 583
 584        mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
 585        if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
 586                return -EINVAL;
 587
 588        nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
 589        if (!nreg)
 590                return -ENOMEM;
 591
 592        spin_lock_bh(&wdev->mgmt_registrations_lock);
 593
 594        list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
 595                int mlen = min(match_len, reg->match_len);
 596
 597                if (frame_type != le16_to_cpu(reg->frame_type))
 598                        continue;
 599
 600                if (memcmp(reg->match, match_data, mlen) == 0) {
 601                        err = -EALREADY;
 602                        break;
 603                }
 604        }
 605
 606        if (err) {
 607                kfree(nreg);
 608                goto out;
 609        }
 610
 611        memcpy(nreg->match, match_data, match_len);
 612        nreg->match_len = match_len;
 613        nreg->nlportid = snd_portid;
 614        nreg->frame_type = cpu_to_le16(frame_type);
 615        list_add(&nreg->list, &wdev->mgmt_registrations);
 616
 617        if (rdev->ops->mgmt_frame_register)
 618                rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
 619
 620 out:
 621        spin_unlock_bh(&wdev->mgmt_registrations_lock);
 622
 623        return err;
 624}
 625
 626void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
 627{
 628        struct wiphy *wiphy = wdev->wiphy;
 629        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 630        struct cfg80211_mgmt_registration *reg, *tmp;
 631
 632        spin_lock_bh(&wdev->mgmt_registrations_lock);
 633
 634        list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 635                if (reg->nlportid != nlportid)
 636                        continue;
 637
 638                if (rdev->ops->mgmt_frame_register) {
 639                        u16 frame_type = le16_to_cpu(reg->frame_type);
 640
 641                        rdev_mgmt_frame_register(rdev, wdev,
 642                                                 frame_type, false);
 643                }
 644
 645                list_del(&reg->list);
 646                kfree(reg);
 647        }
 648
 649        spin_unlock_bh(&wdev->mgmt_registrations_lock);
 650
 651        if (nlportid && rdev->crit_proto_nlportid == nlportid) {
 652                rdev->crit_proto_nlportid = 0;
 653                rdev_crit_proto_stop(rdev, wdev);
 654        }
 655
 656        if (nlportid == wdev->ap_unexpected_nlportid)
 657                wdev->ap_unexpected_nlportid = 0;
 658}
 659
 660void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
 661{
 662        struct cfg80211_mgmt_registration *reg, *tmp;
 663
 664        spin_lock_bh(&wdev->mgmt_registrations_lock);
 665
 666        list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 667                list_del(&reg->list);
 668                kfree(reg);
 669        }
 670
 671        spin_unlock_bh(&wdev->mgmt_registrations_lock);
 672}
 673
 674int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 675                          struct wireless_dev *wdev,
 676                          struct ieee80211_channel *chan, bool offchan,
 677                          unsigned int wait, const u8 *buf, size_t len,
 678                          bool no_cck, bool dont_wait_for_ack, u64 *cookie)
 679{
 680        const struct ieee80211_mgmt *mgmt;
 681        u16 stype;
 682
 683        if (!wdev->wiphy->mgmt_stypes)
 684                return -EOPNOTSUPP;
 685
 686        if (!rdev->ops->mgmt_tx)
 687                return -EOPNOTSUPP;
 688
 689        if (len < 24 + 1)
 690                return -EINVAL;
 691
 692        mgmt = (const struct ieee80211_mgmt *) buf;
 693
 694        if (!ieee80211_is_mgmt(mgmt->frame_control))
 695                return -EINVAL;
 696
 697        stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
 698        if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
 699                return -EINVAL;
 700
 701        if (ieee80211_is_action(mgmt->frame_control) &&
 702            mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
 703                int err = 0;
 704
 705                wdev_lock(wdev);
 706
 707                switch (wdev->iftype) {
 708                case NL80211_IFTYPE_ADHOC:
 709                case NL80211_IFTYPE_STATION:
 710                case NL80211_IFTYPE_P2P_CLIENT:
 711                        if (!wdev->current_bss) {
 712                                err = -ENOTCONN;
 713                                break;
 714                        }
 715
 716                        if (!ether_addr_equal(wdev->current_bss->pub.bssid,
 717                                              mgmt->bssid)) {
 718                                err = -ENOTCONN;
 719                                break;
 720                        }
 721
 722                        /*
 723                         * check for IBSS DA must be done by driver as
 724                         * cfg80211 doesn't track the stations
 725                         */
 726                        if (wdev->iftype == NL80211_IFTYPE_ADHOC)
 727                                break;
 728
 729                        /* for station, check that DA is the AP */
 730                        if (!ether_addr_equal(wdev->current_bss->pub.bssid,
 731                                              mgmt->da)) {
 732                                err = -ENOTCONN;
 733                                break;
 734                        }
 735                        break;
 736                case NL80211_IFTYPE_AP:
 737                case NL80211_IFTYPE_P2P_GO:
 738                case NL80211_IFTYPE_AP_VLAN:
 739                        if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
 740                                err = -EINVAL;
 741                        break;
 742                case NL80211_IFTYPE_MESH_POINT:
 743                        if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
 744                                err = -EINVAL;
 745                                break;
 746                        }
 747                        /*
 748                         * check for mesh DA must be done by driver as
 749                         * cfg80211 doesn't track the stations
 750                         */
 751                        break;
 752                case NL80211_IFTYPE_P2P_DEVICE:
 753                        /*
 754                         * fall through, P2P device only supports
 755                         * public action frames
 756                         */
 757                default:
 758                        err = -EOPNOTSUPP;
 759                        break;
 760                }
 761                wdev_unlock(wdev);
 762
 763                if (err)
 764                        return err;
 765        }
 766
 767        if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
 768                return -EINVAL;
 769
 770        /* Transmit the Action frame as requested by user space */
 771        return rdev_mgmt_tx(rdev, wdev, chan, offchan,
 772                            wait, buf, len, no_cck, dont_wait_for_ack,
 773                            cookie);
 774}
 775
 776bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
 777                      const u8 *buf, size_t len, gfp_t gfp)
 778{
 779        struct wiphy *wiphy = wdev->wiphy;
 780        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 781        struct cfg80211_mgmt_registration *reg;
 782        const struct ieee80211_txrx_stypes *stypes =
 783                &wiphy->mgmt_stypes[wdev->iftype];
 784        struct ieee80211_mgmt *mgmt = (void *)buf;
 785        const u8 *data;
 786        int data_len;
 787        bool result = false;
 788        __le16 ftype = mgmt->frame_control &
 789                cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
 790        u16 stype;
 791
 792        trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm);
 793        stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
 794
 795        if (!(stypes->rx & BIT(stype))) {
 796                trace_cfg80211_return_bool(false);
 797                return false;
 798        }
 799
 800        data = buf + ieee80211_hdrlen(mgmt->frame_control);
 801        data_len = len - ieee80211_hdrlen(mgmt->frame_control);
 802
 803        spin_lock_bh(&wdev->mgmt_registrations_lock);
 804
 805        list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
 806                if (reg->frame_type != ftype)
 807                        continue;
 808
 809                if (reg->match_len > data_len)
 810                        continue;
 811
 812                if (memcmp(reg->match, data, reg->match_len))
 813                        continue;
 814
 815                /* found match! */
 816
 817                /* Indicate the received Action frame to user space */
 818                if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
 819                                      freq, sig_mbm,
 820                                      buf, len, gfp))
 821                        continue;
 822
 823                result = true;
 824                break;
 825        }
 826
 827        spin_unlock_bh(&wdev->mgmt_registrations_lock);
 828
 829        trace_cfg80211_return_bool(result);
 830        return result;
 831}
 832EXPORT_SYMBOL(cfg80211_rx_mgmt);
 833
 834void cfg80211_dfs_channels_update_work(struct work_struct *work)
 835{
 836        struct delayed_work *delayed_work;
 837        struct cfg80211_registered_device *rdev;
 838        struct cfg80211_chan_def chandef;
 839        struct ieee80211_supported_band *sband;
 840        struct ieee80211_channel *c;
 841        struct wiphy *wiphy;
 842        bool check_again = false;
 843        unsigned long timeout, next_time = 0;
 844        int bandid, i;
 845
 846        delayed_work = container_of(work, struct delayed_work, work);
 847        rdev = container_of(delayed_work, struct cfg80211_registered_device,
 848                            dfs_update_channels_wk);
 849        wiphy = &rdev->wiphy;
 850
 851        mutex_lock(&cfg80211_mutex);
 852        for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
 853                sband = wiphy->bands[bandid];
 854                if (!sband)
 855                        continue;
 856
 857                for (i = 0; i < sband->n_channels; i++) {
 858                        c = &sband->channels[i];
 859
 860                        if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
 861                                continue;
 862
 863                        timeout = c->dfs_state_entered +
 864                                  IEEE80211_DFS_MIN_NOP_TIME_MS;
 865
 866                        if (time_after_eq(jiffies, timeout)) {
 867                                c->dfs_state = NL80211_DFS_USABLE;
 868                                cfg80211_chandef_create(&chandef, c,
 869                                                        NL80211_CHAN_NO_HT);
 870
 871                                nl80211_radar_notify(rdev, &chandef,
 872                                                     NL80211_RADAR_NOP_FINISHED,
 873                                                     NULL, GFP_ATOMIC);
 874                                continue;
 875                        }
 876
 877                        if (!check_again)
 878                                next_time = timeout - jiffies;
 879                        else
 880                                next_time = min(next_time, timeout - jiffies);
 881                        check_again = true;
 882                }
 883        }
 884        mutex_unlock(&cfg80211_mutex);
 885
 886        /* reschedule if there are other channels waiting to be cleared again */
 887        if (check_again)
 888                queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
 889                                   next_time);
 890}
 891
 892
 893void cfg80211_radar_event(struct wiphy *wiphy,
 894                          struct cfg80211_chan_def *chandef,
 895                          gfp_t gfp)
 896{
 897        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 898        unsigned long timeout;
 899
 900        trace_cfg80211_radar_event(wiphy, chandef);
 901
 902        /* only set the chandef supplied channel to unavailable, in
 903         * case the radar is detected on only one of multiple channels
 904         * spanned by the chandef.
 905         */
 906        cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
 907
 908        timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
 909        queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
 910                           timeout);
 911
 912        nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
 913}
 914EXPORT_SYMBOL(cfg80211_radar_event);
 915
 916void cfg80211_cac_event(struct net_device *netdev,
 917                        enum nl80211_radar_event event, gfp_t gfp)
 918{
 919        struct wireless_dev *wdev = netdev->ieee80211_ptr;
 920        struct wiphy *wiphy = wdev->wiphy;
 921        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 922        struct cfg80211_chan_def chandef;
 923        unsigned long timeout;
 924
 925        trace_cfg80211_cac_event(netdev, event);
 926
 927        if (WARN_ON(!wdev->cac_started))
 928                return;
 929
 930        if (WARN_ON(!wdev->channel))
 931                return;
 932
 933        cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
 934
 935        switch (event) {
 936        case NL80211_RADAR_CAC_FINISHED:
 937                timeout = wdev->cac_start_time +
 938                          msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
 939                WARN_ON(!time_after_eq(jiffies, timeout));
 940                cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE);
 941                break;
 942        case NL80211_RADAR_CAC_ABORTED:
 943                break;
 944        default:
 945                WARN_ON(1);
 946                return;
 947        }
 948        wdev->cac_started = false;
 949
 950        nl80211_radar_notify(rdev, &chandef, event, netdev, gfp);
 951}
 952EXPORT_SYMBOL(cfg80211_cac_event);
 953