]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/wireless/nl80211.c
Merge tag 'mac80211-next-for-davem-2019-04-26' of git://git.kernel.org/pub/scm/linux...
[linux.git] / net / wireless / nl80211.c
index 25a9e3b5c1542a71fff0f4f2ab8166f977786f8c..e74d21f4108a0688a50a5bd315fea4dc3361ea85 100644 (file)
@@ -331,6 +331,11 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
                                               .len = NL80211_MAX_SUPP_RATES },
        [NL80211_ATTR_STA_PLINK_ACTION] =
                NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
+       [NL80211_ATTR_STA_TX_POWER_SETTING] =
+               NLA_POLICY_RANGE(NLA_U8,
+                                NL80211_TX_POWER_AUTOMATIC,
+                                NL80211_TX_POWER_FIXED),
+       [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
        [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
        [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
        [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
@@ -553,6 +558,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
        [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
        [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
        [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+       [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
 };
 
 /* policy for the key default flags */
@@ -617,12 +623,21 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
        [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
 };
 
+static const struct nla_policy
+nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
+       [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
+       [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
+       [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
+};
+
 static const struct nla_policy
 nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
        [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
                                                 .len = IEEE80211_MAX_SSID_LEN },
        [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
        [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
+       [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
+               NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
 };
 
 static const struct nla_policy
@@ -958,6 +973,9 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
                k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
        }
 
+       if (tb[NL80211_KEY_MODE])
+               k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
+
        return 0;
 }
 
@@ -3634,8 +3652,11 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
        if (key.idx < 0)
                return -EINVAL;
 
-       /* only support setting default key */
-       if (!key.def && !key.defmgmt)
+       /* Only support setting default key and
+        * Extended Key ID action NL80211_KEY_SET_TX.
+        */
+       if (!key.def && !key.defmgmt &&
+           !(key.p.mode == NL80211_KEY_SET_TX))
                return -EINVAL;
 
        wdev_lock(dev->ieee80211_ptr);
@@ -3659,7 +3680,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 #ifdef CONFIG_CFG80211_WEXT
                dev->ieee80211_ptr->wext.default_key = key.idx;
 #endif
-       } else {
+       } else if (key.defmgmt) {
                if (key.def_uni || !key.def_multi) {
                        err = -EINVAL;
                        goto out;
@@ -3681,8 +3702,25 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 #ifdef CONFIG_CFG80211_WEXT
                dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
 #endif
-       }
+       } else if (key.p.mode == NL80211_KEY_SET_TX &&
+                  wiphy_ext_feature_isset(&rdev->wiphy,
+                                          NL80211_EXT_FEATURE_EXT_KEY_ID)) {
+               u8 *mac_addr = NULL;
+
+               if (info->attrs[NL80211_ATTR_MAC])
+                       mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+               if (!mac_addr || key.idx < 0 || key.idx > 1) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
+               err = rdev_add_key(rdev, dev, key.idx,
+                                  NL80211_KEYTYPE_PAIRWISE,
+                                  mac_addr, &key.p);
+       } else {
+               err = -EINVAL;
+       }
  out:
        wdev_unlock(dev->ieee80211_ptr);
 
@@ -3843,8 +3881,7 @@ static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
        if (n_entries > wiphy->max_acl_mac_addrs)
                return ERR_PTR(-ENOTSUPP);
 
-       acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
-                     GFP_KERNEL);
+       acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
        if (!acl)
                return ERR_PTR(-ENOMEM);
 
@@ -4889,6 +4926,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
        PUT_SINFO(TX_RETRIES, tx_retries, u32);
        PUT_SINFO(TX_FAILED, tx_failed, u32);
        PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
+       PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
        PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
        PUT_SINFO(LOCAL_PM, local_pm, u32);
        PUT_SINFO(PEER_PM, peer_pm, u32);
@@ -5387,6 +5425,36 @@ static int nl80211_set_station_tdls(struct genl_info *info,
        return nl80211_parse_sta_wme(info, params);
 }
 
+static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
+                                            struct station_parameters *params)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       int idx;
+
+       if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
+               if (!rdev->ops->set_tx_power ||
+                   !wiphy_ext_feature_isset(&rdev->wiphy,
+                                        NL80211_EXT_FEATURE_STA_TX_PWR))
+                       return -EOPNOTSUPP;
+
+               idx = NL80211_ATTR_STA_TX_POWER_SETTING;
+               params->txpwr.type = nla_get_u8(info->attrs[idx]);
+
+               if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
+                       idx = NL80211_ATTR_STA_TX_POWER;
+
+                       if (info->attrs[idx])
+                               params->txpwr.power =
+                                       nla_get_s16(info->attrs[idx]);
+                       else
+                               return -EINVAL;
+               }
+               params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
+       }
+
+       return 0;
+}
+
 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -5480,6 +5548,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                                     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
                return -EOPNOTSUPP;
 
+       err = nl80211_parse_sta_txpower_setting(info, &params);
+       if (err)
+               return err;
+
        /* Include parameters for TDLS peer (will check later) */
        err = nl80211_set_station_tdls(info, &params);
        if (err)
@@ -5617,6 +5689,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
                                     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
                return -EOPNOTSUPP;
 
+       err = nl80211_parse_sta_txpower_setting(info, &params);
+       if (err)
+               return err;
+
        err = nl80211_parse_sta_channel_info(info, &params);
        if (err)
                return err;
@@ -6882,7 +6958,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
        struct nlattr *nl_reg_rule;
        char *alpha2;
        int rem_reg_rules, r;
-       u32 num_rules = 0, rule_idx = 0, size_of_regd;
+       u32 num_rules = 0, rule_idx = 0;
        enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
        struct ieee80211_regdomain *rd;
 
@@ -6907,10 +6983,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
        if (!reg_is_valid_request(alpha2))
                return -EINVAL;
 
-       size_of_regd = sizeof(struct ieee80211_regdomain) +
-                      num_rules * sizeof(struct ieee80211_reg_rule);
-
-       rd = kzalloc(size_of_regd, GFP_KERNEL);
+       rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
        if (!rd)
                return -ENOMEM;
 
@@ -7537,6 +7610,41 @@ nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
        return 0;
 }
 
+static int
+nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
+                                      struct cfg80211_match_set *match_sets,
+                                      struct nlattr *tb_band_rssi,
+                                      s32 rssi_thold)
+{
+       struct nlattr *attr;
+       int i, tmp, ret = 0;
+
+       if (!wiphy_ext_feature_isset(wiphy,
+                   NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
+               if (tb_band_rssi)
+                       ret = -EOPNOTSUPP;
+               else
+                       for (i = 0; i < NUM_NL80211_BANDS; i++)
+                               match_sets->per_band_rssi_thold[i] =
+                                       NL80211_SCAN_RSSI_THOLD_OFF;
+               return ret;
+       }
+
+       for (i = 0; i < NUM_NL80211_BANDS; i++)
+               match_sets->per_band_rssi_thold[i] = rssi_thold;
+
+       nla_for_each_nested(attr, tb_band_rssi, tmp) {
+               enum nl80211_band band = nla_type(attr);
+
+               if (band < 0 || band >= NUM_NL80211_BANDS)
+                       return -EINVAL;
+
+               match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
+       }
+
+       return 0;
+}
+
 static struct cfg80211_sched_scan_request *
 nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
                         struct nlattr **attrs, int max_match_sets)
@@ -7776,43 +7884,55 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
                                goto out_free;
                        ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
                        bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
-                       if (ssid || bssid) {
-                               if (WARN_ON(i >= n_match_sets)) {
-                                       /* this indicates a programming error,
-                                        * the loop above should have verified
-                                        * things properly
-                                        */
+
+                       if (!ssid && !bssid) {
+                               i++;
+                               continue;
+                       }
+
+                       if (WARN_ON(i >= n_match_sets)) {
+                               /* this indicates a programming error,
+                                * the loop above should have verified
+                                * things properly
+                                */
+                               err = -EINVAL;
+                               goto out_free;
+                       }
+
+                       if (ssid) {
+                               if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
                                        err = -EINVAL;
                                        goto out_free;
                                }
-
-                               if (ssid) {
-                                       if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
-                                               err = -EINVAL;
-                                               goto out_free;
-                                       }
-                                       memcpy(request->match_sets[i].ssid.ssid,
-                                              nla_data(ssid), nla_len(ssid));
-                                       request->match_sets[i].ssid.ssid_len =
-                                               nla_len(ssid);
-                               }
-                               if (bssid) {
-                                       if (nla_len(bssid) != ETH_ALEN) {
-                                               err = -EINVAL;
-                                               goto out_free;
-                                       }
-                                       memcpy(request->match_sets[i].bssid,
-                                              nla_data(bssid), ETH_ALEN);
+                               memcpy(request->match_sets[i].ssid.ssid,
+                                      nla_data(ssid), nla_len(ssid));
+                               request->match_sets[i].ssid.ssid_len =
+                                       nla_len(ssid);
+                       }
+                       if (bssid) {
+                               if (nla_len(bssid) != ETH_ALEN) {
+                                       err = -EINVAL;
+                                       goto out_free;
                                }
+                               memcpy(request->match_sets[i].bssid,
+                                      nla_data(bssid), ETH_ALEN);
+                       }
 
-                               /* special attribute - old implementation w/a */
+                       /* special attribute - old implementation w/a */
+                       request->match_sets[i].rssi_thold = default_match_rssi;
+                       rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
+                       if (rssi)
                                request->match_sets[i].rssi_thold =
-                                       default_match_rssi;
-                               rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-                               if (rssi)
-                                       request->match_sets[i].rssi_thold =
-                                               nla_get_s32(rssi);
-                       }
+                                       nla_get_s32(rssi);
+
+                       /* Parse per band RSSI attribute */
+                       err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
+                               &request->match_sets[i],
+                               tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
+                               request->match_sets[i].rssi_thold);
+                       if (err)
+                               goto out_free;
+
                        i++;
                }
 
@@ -8061,7 +8181,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
 
        cfg80211_sched_dfs_chan_update(rdev);
 
-       memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
+       rdev->radar_chandef = chandef;
 
        /* Propagate this notification to other radios as well */
        queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
@@ -13259,6 +13379,72 @@ static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
        return -ENOBUFS;
 }
 
+static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct cfg80211_update_owe_info owe_info;
+       struct net_device *dev = info->user_ptr[1];
+
+       if (!rdev->ops->update_owe_info)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
+           !info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       memset(&owe_info, 0, sizeof(owe_info));
+       owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+       nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
+
+       if (info->attrs[NL80211_ATTR_IE]) {
+               owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+               owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+       }
+
+       return rdev_update_owe_info(rdev, dev, &owe_info);
+}
+
+static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct station_info sinfo = {};
+       const u8 *buf;
+       size_t len;
+       u8 *dest;
+       int err;
+
+       if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_MAC] ||
+           !info->attrs[NL80211_ATTR_FRAME]) {
+               GENL_SET_ERR_MSG(info, "Frame or MAC missing");
+               return -EINVAL;
+       }
+
+       if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
+               return -EOPNOTSUPP;
+
+       dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
+       buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+       len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+
+       if (len < sizeof(struct ethhdr))
+               return -EINVAL;
+
+       if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
+           !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
+               return -EINVAL;
+
+       err = rdev_get_station(rdev, dev, dest, &sinfo);
+       if (err)
+               return err;
+
+       return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
+}
+
 #define NL80211_FLAG_NEED_WIPHY                0x01
 #define NL80211_FLAG_NEED_NETDEV       0x02
 #define NL80211_FLAG_NEED_RTNL         0x04
@@ -13368,7 +13554,6 @@ static const struct genl_ops nl80211_ops[] = {
                .doit = nl80211_get_wiphy,
                .dumpit = nl80211_dump_wiphy,
                .done = nl80211_dump_wiphy_done,
-               .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13376,7 +13561,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_WIPHY,
                .doit = nl80211_set_wiphy,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_RTNL,
        },
@@ -13384,7 +13568,6 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_GET_INTERFACE,
                .doit = nl80211_get_interface,
                .dumpit = nl80211_dump_interface,
-               .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
                .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13392,7 +13575,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_INTERFACE,
                .doit = nl80211_set_interface,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13400,7 +13582,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_NEW_INTERFACE,
                .doit = nl80211_new_interface,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13408,7 +13589,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_INTERFACE,
                .doit = nl80211_del_interface,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13416,7 +13596,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_KEY,
                .doit = nl80211_get_key,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13424,7 +13603,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_KEY,
                .doit = nl80211_set_key,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL |
@@ -13433,7 +13611,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_NEW_KEY,
                .doit = nl80211_new_key,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL |
@@ -13442,14 +13619,12 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_KEY,
                .doit = nl80211_del_key,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_SET_BEACON,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .doit = nl80211_set_beacon,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -13457,7 +13632,6 @@ static const struct genl_ops nl80211_ops[] = {
        },
        {
                .cmd = NL80211_CMD_START_AP,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .doit = nl80211_start_ap,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -13465,7 +13639,6 @@ static const struct genl_ops nl80211_ops[] = {
        },
        {
                .cmd = NL80211_CMD_STOP_AP,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .doit = nl80211_stop_ap,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -13475,14 +13648,12 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_GET_STATION,
                .doit = nl80211_get_station,
                .dumpit = nl80211_dump_station,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_SET_STATION,
                .doit = nl80211_set_station,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13490,7 +13661,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_NEW_STATION,
                .doit = nl80211_new_station,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13498,7 +13668,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_STATION,
                .doit = nl80211_del_station,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13507,7 +13676,6 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_GET_MPATH,
                .doit = nl80211_get_mpath,
                .dumpit = nl80211_dump_mpath,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13516,7 +13684,6 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_GET_MPP,
                .doit = nl80211_get_mpp,
                .dumpit = nl80211_dump_mpp,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13524,7 +13691,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_MPATH,
                .doit = nl80211_set_mpath,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13532,7 +13698,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_NEW_MPATH,
                .doit = nl80211_new_mpath,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13540,7 +13705,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_MPATH,
                .doit = nl80211_del_mpath,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13548,7 +13712,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_BSS,
                .doit = nl80211_set_bss,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13557,7 +13720,6 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_GET_REG,
                .doit = nl80211_get_reg_do,
                .dumpit = nl80211_get_reg_dump,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_RTNL,
                /* can be retrieved by unprivileged users */
        },
@@ -13565,7 +13727,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_REG,
                .doit = nl80211_set_reg,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_RTNL,
        },
@@ -13573,19 +13734,16 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_REQ_SET_REG,
                .doit = nl80211_req_set_reg,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
        },
        {
                .cmd = NL80211_CMD_RELOAD_REGDB,
                .doit = nl80211_reload_regdb,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
        },
        {
                .cmd = NL80211_CMD_GET_MESH_CONFIG,
                .doit = nl80211_get_mesh_config,
-               .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13593,7 +13751,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_MESH_CONFIG,
                .doit = nl80211_update_mesh_config,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13601,7 +13758,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TRIGGER_SCAN,
                .doit = nl80211_trigger_scan,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13609,20 +13765,17 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_ABORT_SCAN,
                .doit = nl80211_abort_scan,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_GET_SCAN,
-               .policy = nl80211_policy,
                .dumpit = nl80211_dump_scan,
        },
        {
                .cmd = NL80211_CMD_START_SCHED_SCAN,
                .doit = nl80211_start_sched_scan,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13630,7 +13783,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_STOP_SCHED_SCAN,
                .doit = nl80211_stop_sched_scan,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13638,7 +13790,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_AUTHENTICATE,
                .doit = nl80211_authenticate,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL |
@@ -13647,15 +13798,14 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_ASSOCIATE,
                .doit = nl80211_associate,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_DEAUTHENTICATE,
                .doit = nl80211_deauthenticate,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13663,7 +13813,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DISASSOCIATE,
                .doit = nl80211_disassociate,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13671,7 +13820,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_JOIN_IBSS,
                .doit = nl80211_join_ibss,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13679,7 +13827,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_LEAVE_IBSS,
                .doit = nl80211_leave_ibss,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13689,7 +13836,6 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_TESTMODE,
                .doit = nl80211_testmode_do,
                .dumpit = nl80211_testmode_dump,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13698,23 +13844,22 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CONNECT,
                .doit = nl80211_connect,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
                .doit = nl80211_update_connect_params,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_DISCONNECT,
                .doit = nl80211_disconnect,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13722,28 +13867,25 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_WIPHY_NETNS,
                .doit = nl80211_wiphy_netns,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_GET_SURVEY,
-               .policy = nl80211_policy,
                .dumpit = nl80211_dump_survey,
        },
        {
                .cmd = NL80211_CMD_SET_PMKSA,
                .doit = nl80211_setdel_pmksa,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_DEL_PMKSA,
                .doit = nl80211_setdel_pmksa,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13751,7 +13893,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_FLUSH_PMKSA,
                .doit = nl80211_flush_pmksa,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13759,7 +13900,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
                .doit = nl80211_remain_on_channel,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13767,7 +13907,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
                .doit = nl80211_cancel_remain_on_channel,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13775,7 +13914,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
                .doit = nl80211_set_tx_bitrate_mask,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13783,7 +13921,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_REGISTER_FRAME,
                .doit = nl80211_register_mgmt,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13791,7 +13928,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_FRAME,
                .doit = nl80211_tx_mgmt,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13799,7 +13935,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
                .doit = nl80211_tx_mgmt_cancel_wait,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13807,7 +13942,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_POWER_SAVE,
                .doit = nl80211_set_power_save,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13815,7 +13949,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_POWER_SAVE,
                .doit = nl80211_get_power_save,
-               .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13823,7 +13956,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_CQM,
                .doit = nl80211_set_cqm,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13831,7 +13963,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_CHANNEL,
                .doit = nl80211_set_channel,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13839,7 +13970,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_WDS_PEER,
                .doit = nl80211_set_wds_peer,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13847,7 +13977,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_JOIN_MESH,
                .doit = nl80211_join_mesh,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13855,7 +13984,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_LEAVE_MESH,
                .doit = nl80211_leave_mesh,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13863,7 +13991,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_JOIN_OCB,
                .doit = nl80211_join_ocb,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13871,7 +13998,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_LEAVE_OCB,
                .doit = nl80211_leave_ocb,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13880,7 +14006,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_WOWLAN,
                .doit = nl80211_get_wowlan,
-               .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13888,7 +14013,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_WOWLAN,
                .doit = nl80211_set_wowlan,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13897,7 +14021,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
                .doit = nl80211_set_rekey_data,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL |
@@ -13906,7 +14029,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TDLS_MGMT,
                .doit = nl80211_tdls_mgmt,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13914,7 +14036,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TDLS_OPER,
                .doit = nl80211_tdls_oper,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13922,7 +14043,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_UNEXPECTED_FRAME,
                .doit = nl80211_register_unexpected_frame,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13930,7 +14050,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_PROBE_CLIENT,
                .doit = nl80211_probe_client,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13938,7 +14057,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_REGISTER_BEACONS,
                .doit = nl80211_register_beacons,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13946,7 +14064,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_NOACK_MAP,
                .doit = nl80211_set_noack_map,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13954,7 +14071,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_START_P2P_DEVICE,
                .doit = nl80211_start_p2p_device,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13962,7 +14078,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_STOP_P2P_DEVICE,
                .doit = nl80211_stop_p2p_device,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13970,7 +14085,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_START_NAN,
                .doit = nl80211_start_nan,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13978,7 +14092,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_STOP_NAN,
                .doit = nl80211_stop_nan,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13986,7 +14099,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
                .doit = nl80211_nan_add_func,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -13994,7 +14106,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
                .doit = nl80211_nan_del_func,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14002,7 +14113,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
                .doit = nl80211_nan_change_config,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14010,7 +14120,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_MCAST_RATE,
                .doit = nl80211_set_mcast_rate,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14018,7 +14127,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_MAC_ACL,
                .doit = nl80211_set_mac_acl,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14026,7 +14134,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_RADAR_DETECT,
                .doit = nl80211_start_radar_detection,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14034,12 +14141,10 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
                .doit = nl80211_get_protocol_features,
-               .policy = nl80211_policy,
        },
        {
                .cmd = NL80211_CMD_UPDATE_FT_IES,
                .doit = nl80211_update_ft_ies,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14047,7 +14152,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
                .doit = nl80211_crit_protocol_start,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14055,7 +14159,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
                .doit = nl80211_crit_protocol_stop,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14063,14 +14166,12 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_COALESCE,
                .doit = nl80211_get_coalesce,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_SET_COALESCE,
                .doit = nl80211_set_coalesce,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14078,7 +14179,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CHANNEL_SWITCH,
                .doit = nl80211_channel_switch,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14087,15 +14187,14 @@ static const struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_VENDOR,
                .doit = nl80211_vendor_cmd,
                .dumpit = nl80211_vendor_cmd_dump,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_SET_QOS_MAP,
                .doit = nl80211_set_qos_map,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14103,7 +14202,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_ADD_TX_TS,
                .doit = nl80211_add_tx_ts,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14111,7 +14209,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_DEL_TX_TS,
                .doit = nl80211_del_tx_ts,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14119,7 +14216,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
                .doit = nl80211_tdls_channel_switch,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14127,7 +14223,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
                .doit = nl80211_tdls_cancel_channel_switch,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14135,7 +14230,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
                .doit = nl80211_set_multicast_to_unicast,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14143,21 +14237,19 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_SET_PMK,
                .doit = nl80211_set_pmk,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-                                 NL80211_FLAG_NEED_RTNL,
+                                 NL80211_FLAG_NEED_RTNL |
+                                 NL80211_FLAG_CLEAR_SKB,
        },
        {
                .cmd = NL80211_CMD_DEL_PMK,
                .doit = nl80211_del_pmk,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_EXTERNAL_AUTH,
                .doit = nl80211_external_auth,
-               .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14165,7 +14257,6 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
                .doit = nl80211_tx_control_port,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14173,14 +14264,12 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
                .doit = nl80211_get_ftm_responder_stats,
-               .policy = nl80211_policy,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
                .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
                .doit = nl80211_pmsr_start,
-               .policy = nl80211_policy,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14188,7 +14277,20 @@ static const struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_NOTIFY_RADAR,
                .doit = nl80211_notify_radar_detection,
-               .policy = nl80211_policy,
+               .flags = GENL_UNS_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_UPDATE_OWE_INFO,
+               .doit = nl80211_update_owe_info,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_PROBE_MESH_LINK,
+               .doit = nl80211_probe_mesh_link,
                .flags = GENL_UNS_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
@@ -14200,6 +14302,7 @@ static struct genl_family nl80211_fam __ro_after_init = {
        .hdrsize = 0,                   /* no private header */
        .version = 1,                   /* no particular meaning now */
        .maxattr = NL80211_ATTR_MAX,
+       .policy = nl80211_policy,
        .netnsok = true,
        .pre_doit = nl80211_pre_doit,
        .post_doit = nl80211_post_doit,
@@ -15721,6 +15824,11 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
 
        wdev->chandef = *chandef;
        wdev->preset_chandef = *chandef;
+
+       if (wdev->iftype == NL80211_IFTYPE_STATION &&
+           !WARN_ON(!wdev->current_bss))
+               wdev->current_bss->pub.channel = chandef->chan;
+
        nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
                                 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
 }
@@ -16364,6 +16472,46 @@ int cfg80211_external_auth_request(struct net_device *dev,
 }
 EXPORT_SYMBOL(cfg80211_external_auth_request);
 
+void cfg80211_update_owe_info_event(struct net_device *netdev,
+                                   struct cfg80211_update_owe_info *owe_info,
+                                   gfp_t gfp)
+{
+       struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+
+       trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
+       if (!hdr)
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
+               goto nla_put_failure;
+
+       if (!owe_info->ie_len ||
+           nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+
+       genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+                               NL80211_MCGRP_MLME, gfp);
+       return;
+
+nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_update_owe_info_event);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)