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