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