Many changes all over:

* HE (802.11ax) work continues
  * WPA3 offloads
  * work on extended key ID handling continues
  * fixes to honour AP supported rates with auth/assoc frames
  * nl80211 netlink policy improvements to fix some issues
    with strict validation on new commands with old attrs
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl0Dq/sACgkQB8qZga/f
 l8RqFg/+MBcuqvW2xTy5o5Lbw7Drx5ROgFT2ZRAO6PTeboQ43NOBiXt2dEhDbp+w
 mHChImF85px3SFMBSvuf97zlScNV6+VJraDDjoZFixt/gIZ/XsdURo5i4IGmUbfj
 +LY1oPm7suC5Cold+yPicHTukFpeU7cSwceslFsecqiN5unlzIxf6gY9H7OL7WGT
 s0Wis0x3y2m9mMi4cvQfHkFzplcTc5SBgPLyLQtHUNx1eySEZ+AymlNVmbGrRWr9
 vaCU5W9+Wz0N6lEB/UI5y6fZzj5mhkcimGck1Os7dFeC7KWjntjT9iKIkFHWehxi
 QfLcK6pGjLpPpMTQtOEfl34ZGnOyO8N9GmOLaaUaBeaZItabYJwfgbdr7NxiJvta
 1cyqXek+D2G7WOa0aIrWhmwswKGBa3nIBqS/ZP/SEWLEzU1Cn0NiAD5Ba016TC4C
 D+1BBXIdpQDoZCgfd6KkGs2Ynf/8N3OwHW+EwjpAu3IARTQzb6tMWSvkAuAgJt1F
 dBD7NqdFhWXFfxqf9NpB8bkmpyNKM4Km6eO2HKpCg/5suKqYJ1Xj9EeQin1B+QsE
 Jntj69hQ6Kj2gKBPy+RnCBFbxMNuFhpc1kmUOGj9U9aAcOntV0woVOyFGsbRmFo3
 MI8aVU/gjQDCcHHD5xtJGHa11uIefXq1r2H7Um3sxKYeBsqFjP4=
 =j+Um
 -----END PGP SIGNATURE-----

Merge tag 'mac80211-next-for-davem-2019-06-14' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Many changes all over:
 * HE (802.11ax) work continues
 * WPA3 offloads
 * work on extended key ID handling continues
 * fixes to honour AP supported rates with auth/assoc frames
 * nl80211 netlink policy improvements to fix some issues
   with strict validation on new commands with old attrs
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-06-14 11:27:26 -07:00
commit d96ec97511
30 changed files with 498 additions and 171 deletions

View File

@ -226,9 +226,6 @@ TBD
.. kernel-doc:: include/net/mac80211.h
:functions: ieee80211_tx_rate_control
.. kernel-doc:: include/net/mac80211.h
:functions: rate_control_send_low
TBD
This part of the book describes mac80211 internals.

View File

@ -646,9 +646,6 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
il_sta = NULL;
}
if (rate_control_send_low(sta, il_sta, txrc))
return;
rate_mask = sta->supp_rates[sband->band];
/* get user max rate if set */

View File

@ -2224,10 +2224,6 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
il_sta = NULL;
}
/* Send management frames and NO_ACK data using lowest rate. */
if (rate_control_send_low(sta, il_sta, txrc))
return;
if (!lq_sta)
return;

View File

@ -2731,10 +2731,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
priv_sta = NULL;
}
/* Send management frames and NO_ACK data using lowest rate. */
if (rate_control_send_low(sta, priv_sta, txrc))
return;
rate_idx = lq_sta->last_txrate_idx;
if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {

View File

@ -2960,10 +2960,6 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
mvm_sta = NULL;
}
/* Send management frames and NO_ACK data using lowest rate. */
if (rate_control_send_low(sta, mvm_sta, txrc))
return;
if (!mvm_sta)
return;

View File

@ -457,6 +457,8 @@ static struct wiphy_vendor_command mac80211_hwsim_vendor_commands[] = {
.subcmd = QCA_NL80211_SUBCMD_TEST },
.flags = WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = mac80211_hwsim_vendor_cmd_test,
.policy = hwsim_vendor_test_policy,
.maxattr = QCA_WLAN_VENDOR_ATTR_MAX,
}
};

View File

@ -173,9 +173,6 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
u8 try_per_rate, i, rix;
bool not_data = !ieee80211_is_data(fc);
if (rate_control_send_low(sta, priv_sta, txrc))
return;
rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
try_per_rate = 1;
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,

View File

@ -2612,6 +2612,7 @@ enum ieee80211_key_len {
#define FILS_ERP_MAX_RRK_LEN 64
#define PMK_MAX_LEN 64
#define SAE_PASSWORD_MAX_LEN 128
/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */
enum ieee80211_pub_actioncode {
@ -2712,6 +2713,13 @@ enum ieee80211_tdls_actioncode {
#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5)
#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(6)
/*
* When set, indicates that the AP is able to tolerate 26-tone RU UL
* OFDMA transmissions using HE TB PPDU from OBSS (not falsely classify the
* 26-tone RU UL OFDMA transmissions as radar pulses).
*/
#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7)
/* Defines support for enhanced multi-bssid advertisement*/
#define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(1)

View File

@ -381,6 +381,26 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
return NULL;
}
/**
* ieee80211_get_he_iftype_cap - return HE capabilities for an sband's iftype
* @sband: the sband to search for the iftype on
* @iftype: enum nl80211_iftype
*
* Return: pointer to the struct ieee80211_sta_he_cap, or NULL is none found
*/
static inline const struct ieee80211_sta_he_cap *
ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *sband,
u8 iftype)
{
const struct ieee80211_sband_iftype_data *data =
ieee80211_get_sband_iftype_data(sband, iftype);
if (data && data->he_cap.has_he)
return &data->he_cap;
return NULL;
}
/**
* ieee80211_get_he_sta_cap - return HE capabilities for an sband's STA
* @sband: the sband to search for the STA on
@ -390,13 +410,7 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
static inline const struct ieee80211_sta_he_cap *
ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
{
const struct ieee80211_sband_iftype_data *data =
ieee80211_get_sband_iftype_data(sband, NL80211_IFTYPE_STATION);
if (data && data->he_cap.has_he)
return &data->he_cap;
return NULL;
return ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_STATION);
}
/**
@ -742,6 +756,9 @@ struct survey_info {
* CFG80211_MAX_WEP_KEYS WEP keys
* @wep_tx_key: key index (0..3) of the default TX static WEP key
* @psk: PSK (for devices supporting 4-way-handshake offload)
* @sae_pwd: password for SAE authentication (for devices supporting SAE
* offload)
* @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
*/
struct cfg80211_crypto_settings {
u32 wpa_versions;
@ -757,6 +774,8 @@ struct cfg80211_crypto_settings {
struct key_params *wep_keys;
int wep_tx_key;
const u8 *psk;
const u8 *sae_pwd;
u8 sae_pwd_len;
};
/**
@ -878,6 +897,7 @@ enum cfg80211_ap_settings_flags {
* @he_cap: HE capabilities (or %NULL if HE isn't enabled)
* @ht_required: stations must support HT
* @vht_required: stations must support VHT
* @twt_responder: Enable Target Wait Time
* @flags: flags, as defined in enum cfg80211_ap_settings_flags
*/
struct cfg80211_ap_settings {
@ -904,6 +924,7 @@ struct cfg80211_ap_settings {
const struct ieee80211_vht_cap *vht_cap;
const struct ieee80211_he_cap_elem *he_cap;
bool ht_required, vht_required;
bool twt_responder;
u32 flags;
};
@ -4151,6 +4172,8 @@ struct sta_opmode_info {
u8 rx_nss;
};
#define VENDOR_CMD_RAW_DATA ((const struct nla_policy *)ERR_PTR(-ENODATA))
/**
* struct wiphy_vendor_command - vendor command definition
* @info: vendor command identifying information, as used in nl80211
@ -4161,6 +4184,10 @@ struct sta_opmode_info {
* @dumpit: dump callback, for transferring bigger/multiple items. The
* @storage points to cb->args[5], ie. is preserved over the multiple
* dumpit calls.
* @policy: policy pointer for attributes within %NL80211_ATTR_VENDOR_DATA.
* Set this to %VENDOR_CMD_RAW_DATA if no policy can be given and the
* attribute is just raw data (e.g. a firmware command).
* @maxattr: highest attribute number in policy
* It's recommended to not have the same sub command with both @doit and
* @dumpit, so that userspace can assume certain ones are get and others
* are used with dump requests.
@ -4173,6 +4200,8 @@ struct wiphy_vendor_command {
int (*dumpit)(struct wiphy *wiphy, struct wireless_dev *wdev,
struct sk_buff *skb, const void *data, int data_len,
unsigned long *storage);
const struct nla_policy *policy;
unsigned int maxattr;
};
/**
@ -5721,6 +5750,26 @@ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
*/
void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
/**
* cfg80211_bss_iter - iterate all BSS entries
*
* This function iterates over the BSS entries associated with the given wiphy
* and calls the callback for the iterated BSS. The iterator function is not
* allowed to call functions that might modify the internal state of the BSS DB.
*
* @wiphy: the wiphy
* @chandef: if given, the iterator function will be called only if the channel
* of the currently iterated BSS is a subset of the given channel.
* @iter: the iterator function to call
* @iter_data: an argument to the iterator function
*/
void cfg80211_bss_iter(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef,
void (*iter)(struct wiphy *wiphy,
struct cfg80211_bss *bss,
void *data),
void *iter_data);
static inline enum nl80211_bss_scan_width
cfg80211_chandef_to_scan_width(const struct cfg80211_chan_def *chandef)
{
@ -6231,8 +6280,11 @@ struct cfg80211_fils_resp_params {
* case.
* @bssid: The BSSID of the AP (may be %NULL)
* @bss: Entry of bss to which STA got connected to, can be obtained through
* cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
* @bss needs to be specified.
* cfg80211_get_bss() (may be %NULL). But it is recommended to store the
* bss from the connect_request and hold a reference to it and return
* through this param to avoid a warning if the bss is expired during the
* connection, esp. for those drivers implementing connect op.
* Only one parameter among @bssid and @bss needs to be specified.
* @req_ie: Association request IEs (may be %NULL)
* @req_ie_len: Association request IEs length
* @resp_ie: Association response IEs (may be %NULL)
@ -6280,8 +6332,12 @@ void cfg80211_connect_done(struct net_device *dev,
*
* @dev: network device
* @bssid: the BSSID of the AP
* @bss: entry of bss to which STA got connected to, can be obtained
* through cfg80211_get_bss (may be %NULL)
* @bss: Entry of bss to which STA got connected to, can be obtained through
* cfg80211_get_bss() (may be %NULL). But it is recommended to store the
* bss from the connect_request and hold a reference to it and return
* through this param to avoid a warning if the bss is expired during the
* connection, esp. for those drivers implementing connect op.
* Only one parameter among @bssid and @bss needs to be specified.
* @req_ie: association request IEs (maybe be %NULL)
* @req_ie_len: association request IEs length
* @resp_ie: association response IEs (may be %NULL)
@ -6491,6 +6547,16 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
struct ieee80211_channel *chan,
gfp_t gfp);
/**
* cfg80211_tx_mgmt_expired - tx_mgmt duration expired
* @wdev: wireless device
* @cookie: the requested cookie
* @chan: The current channel (from tx_mgmt request)
* @gfp: allocation flags
*/
void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
struct ieee80211_channel *chan, gfp_t gfp);
/**
* cfg80211_sinfo_alloc_tid_stats - allocate per-tid statistics.
*

View File

@ -317,6 +317,7 @@ struct ieee80211_vif_chanctx_switch {
* @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
* @BSS_CHANGED_FTM_RESPONDER: fime timing reasurement request responder
* functionality changed for this BSS (AP mode).
* @BSS_CHANGED_TWT: TWT status changed
*
*/
enum ieee80211_bss_change {
@ -347,6 +348,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_KEEP_ALIVE = 1<<24,
BSS_CHANGED_MCAST_RATE = 1<<25,
BSS_CHANGED_FTM_RESPONDER = 1<<26,
BSS_CHANGED_TWT = 1<<27,
/* when adding here, make sure to change ieee80211_reconfig */
};
@ -504,6 +506,8 @@ struct ieee80211_ftm_responder_params {
* @he_support: does this BSS support HE
* @twt_requester: does this BSS support TWT requester (relevant for managed
* mode only, set if the AP advertises TWT responder role)
* @twt_responder: does this BSS support TWT requester (relevant for managed
* mode only, set if the AP advertises TWT responder role)
* @assoc: association status
* @ibss_joined: indicates whether this station is part of an IBSS
* or not
@ -611,6 +615,7 @@ struct ieee80211_bss_conf {
u16 frame_time_rts_th;
bool he_support;
bool twt_requester;
bool twt_responder;
/* association related data */
bool assoc, ibss_joined;
bool ibss_creator;
@ -2269,6 +2274,9 @@ struct ieee80211_txq {
* @IEEE80211_HW_EXT_KEY_ID_NATIVE: Driver and hardware are supporting Extended
* Key ID and can handle two unicast keys per station for Rx and Tx.
*
* @IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT: The card/driver can't handle
* active Tx A-MPDU sessions with Extended Key IDs during rekey.
*
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@ -2321,6 +2329,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_MULTI_BSSID,
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
IEEE80211_HW_EXT_KEY_ID_NATIVE,
IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@ -5951,29 +5960,6 @@ static inline int rate_supported(struct ieee80211_sta *sta,
return (sta == NULL || sta->supp_rates[band] & BIT(index));
}
/**
* rate_control_send_low - helper for drivers for management/no-ack frames
*
* Rate control algorithms that agree to use the lowest rate to
* send management frames and NO_ACK data with the respective hw
* retries should use this in the beginning of their mac80211 get_rate
* callback. If true is returned the rate control can simply return.
* If false is returned we guarantee that sta and sta and priv_sta is
* not null.
*
* Rate control algorithms wishing to do more intelligent selection of
* rate for multicast/broadcast frames may choose to not use this.
*
* @sta: &struct ieee80211_sta pointer to the target destination. Note
* that this may be null.
* @priv_sta: private rate control structure. This may be null.
* @txrc: rate control information we sholud populate for mac80211.
*/
bool rate_control_send_low(struct ieee80211_sta *sta,
void *priv_sta,
struct ieee80211_tx_rate_control *txrc);
static inline s8
rate_lowest_index(struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta)

View File

@ -1754,6 +1754,15 @@ static inline int __nla_validate_nested(const struct nlattr *start, int maxtype,
validate, extack);
}
static inline int
nl80211_validate_nested(const struct nlattr *start, int maxtype,
const struct nla_policy *policy,
struct netlink_ext_ack *extack)
{
return __nla_validate_nested(start, maxtype, policy,
NL_VALIDATE_STRICT, extack);
}
static inline int
nla_validate_nested_deprecated(const struct nlattr *start, int maxtype,
const struct nla_policy *policy,

View File

@ -234,6 +234,15 @@
* use in a FILS shared key connection with PMKSA caching.
*/
/**
* DOC: SAE authentication offload
*
* By setting @NL80211_EXT_FEATURE_SAE_OFFLOAD flag drivers can indicate they
* support offloading SAE authentication for WPA3-Personal networks. In
* %NL80211_CMD_CONNECT the password for SAE should be specified using
* %NL80211_ATTR_SAE_PASSWORD.
*/
/**
* enum nl80211_commands - supported nl80211 commands
*
@ -2341,6 +2350,12 @@ enum nl80211_commands {
* should be picking up the lowest tx power, either tx power per-interface
* or per-station.
*
* @NL80211_ATTR_SAE_PASSWORD: attribute for passing SAE password material. It
* is used with %NL80211_CMD_CONNECT to provide password for offloading
* SAE authentication for WPA3-Personal networks.
*
* @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@ -2794,6 +2809,10 @@ enum nl80211_attrs {
NL80211_ATTR_STA_TX_POWER_SETTING,
NL80211_ATTR_STA_TX_POWER,
NL80211_ATTR_SAE_PASSWORD,
NL80211_ATTR_TWT_RESPONDER,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@ -4406,6 +4425,7 @@ enum nl80211_mfp {
enum nl80211_wpa_versions {
NL80211_WPA_VERSION_1 = 1 << 0,
NL80211_WPA_VERSION_2 = 1 << 1,
NL80211_WPA_VERSION_3 = 1 << 2,
};
/**
@ -5422,6 +5442,9 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
* to a station.
*
* @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
* station mode (SAE password is passed as part of the connect command).
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@ -5466,6 +5489,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
NL80211_EXT_FEATURE_EXT_KEY_ID,
NL80211_EXT_FEATURE_STA_TX_PWR,
NL80211_EXT_FEATURE_SAE_OFFLOAD,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,

View File

@ -4,7 +4,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018-2019 Intel Corporation
*
* This file is GPLv2 as found in COPYING.
*/
@ -975,7 +975,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
BSS_CHANGED_BEACON |
BSS_CHANGED_SSID |
BSS_CHANGED_P2P_PS |
BSS_CHANGED_TXPOWER;
BSS_CHANGED_TXPOWER |
BSS_CHANGED_TWT;
int err;
int prev_beacon_int;
@ -1045,6 +1046,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata->vif.bss_conf.dtim_period = params->dtim_period;
sdata->vif.bss_conf.enable_beacon = true;
sdata->vif.bss_conf.allow_p2p_go_ps = sdata->vif.p2p;
sdata->vif.bss_conf.twt_responder = params->twt_responder;
sdata->vif.bss_conf.ssid_len = params->ssid_len;
if (params->ssid_len)
@ -1466,7 +1468,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
return ret;
}
if (params->supported_rates) {
if (params->supported_rates && params->supported_rates_len) {
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
sband, params->supported_rates,
params->supported_rates_len,

View File

@ -274,6 +274,7 @@ static const char *hw_flag_names[] = {
FLAG(SUPPORTS_MULTI_BSSID),
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
FLAG(EXT_KEY_ID_NATIVE),
FLAG(NO_AMPDU_KEYBORDER_SUPPORT),
#undef FLAG
};

View File

@ -342,9 +342,6 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
key->debugfs.dir = debugfs_create_dir(buf,
key->local->debugfs.keys);
if (!key->debugfs.dir)
return;
sta = key->sta;
if (sta) {
sprintf(buf, "../../netdev:%s/stations/%pM",

View File

@ -818,9 +818,8 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
sprintf(buf, "netdev:%s", sdata->name);
sdata->vif.debugfs_dir = debugfs_create_dir(buf,
sdata->local->hw.wiphy->debugfsdir);
if (sdata->vif.debugfs_dir)
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
sdata->vif.debugfs_dir);
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
sdata->vif.debugfs_dir);
add_files(sdata);
}
@ -845,8 +844,5 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
return;
sprintf(buf, "netdev:%s", sdata->name);
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
sdata_err(sdata,
"debugfs: failed to rename debugfs dir to %s\n",
buf);
debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
}

View File

@ -960,8 +960,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
* dir might still be around.
*/
sta->debugfs_dir = debugfs_create_dir(mac, stations_dir);
if (!sta->debugfs_dir)
return;
DEBUGFS_ADD(flags);
DEBUGFS_ADD(aid);

View File

@ -274,50 +274,61 @@ int ieee80211_set_tx_key(struct ieee80211_key *key)
old = key_mtx_dereference(local, sta->ptk[sta->ptk_idx]);
sta->ptk_idx = key->conf.keyidx;
if (ieee80211_hw_check(&local->hw, NO_AMPDU_KEYBORDER_SUPPORT))
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_check_fast_xmit(sta);
return 0;
}
static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
struct ieee80211_key *new_key,
bool pairwise)
static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
struct ieee80211_key *new)
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_local *local;
struct sta_info *sta;
int ret;
struct ieee80211_local *local = new->local;
struct sta_info *sta = new->sta;
int i;
/* Aggregation sessions are OK when running on SW crypto.
* A broken remote STA may cause issues not observed with HW
* crypto, though.
*/
if (!(old_key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
return 0;
assert_key_lock(local);
assert_key_lock(old_key->local);
sta = old_key->sta;
if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
/* Extended Key ID key install, initial one or rekey */
/* Unicast rekey without Extended Key ID needs special handling */
if (new_key && sta && pairwise &&
rcu_access_pointer(sta->ptk[sta->ptk_idx]) == old_key) {
local = old_key->local;
sdata = old_key->sdata;
/* Stop TX till we are on the new key */
old_key->flags |= KEY_FLAG_TAINTED;
ieee80211_clear_fast_xmit(sta);
/* Aggregation sessions during rekey are complicated due to the
* reorder buffer and retransmits. Side step that by blocking
* aggregation during rekey and tear down running sessions.
if (sta->ptk_idx != INVALID_PTK_KEYIDX &&
ieee80211_hw_check(&local->hw,
NO_AMPDU_KEYBORDER_SUPPORT)) {
/* Aggregation Sessions with Extended Key ID must not
* mix MPDUs with different keyIDs within one A-MPDU.
* Tear down any running Tx aggregation and all new
* Rx/Tx aggregation request during rekey if the driver
* asks us to do so. (Blocking Tx only would be
* sufficient but WLAN_STA_BLOCK_BA gets the job done
* for the few ms we need it.)
*/
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
mutex_lock(&sta->ampdu_mlme.mtx);
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
___ieee80211_stop_tx_ba_session(sta, i,
AGG_STOP_LOCAL_REQUEST);
mutex_unlock(&sta->ampdu_mlme.mtx);
}
} else if (old) {
/* Rekey without Extended Key ID.
* Aggregation sessions are OK when running on SW crypto.
* A broken remote STA may cause issues not observed with HW
* crypto, though.
*/
if (!(old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
return;
/* Stop Tx till we are on the new key */
old->flags |= KEY_FLAG_TAINTED;
ieee80211_clear_fast_xmit(sta);
if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) {
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
ieee80211_sta_tear_down_BA_sessions(sta,
AGG_STOP_LOCAL_REQUEST);
}
if (!wiphy_ext_feature_isset(local->hw.wiphy,
NL80211_EXT_FEATURE_CAN_REPLACE_PTK0)) {
pr_warn_ratelimited("Rekeying PTK for STA %pM but driver can't safely do that.",
@ -325,18 +336,9 @@ static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
/* Flushing the driver queues *may* help prevent
* the clear text leaks and freezes.
*/
ieee80211_flush_queues(local, sdata, false);
ieee80211_flush_queues(local, old->sdata, false);
}
}
ieee80211_key_disable_hw_accel(old_key);
if (new_key)
ret = ieee80211_key_enable_hw_accel(new_key);
else
ret = 0;
return ret;
}
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
@ -394,7 +396,6 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&sdata->local->key_mtx);
}
static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
bool pairwise,
@ -402,7 +403,7 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
struct ieee80211_key *new)
{
int idx;
int ret;
int ret = 0;
bool defunikey, defmultikey, defmgmtkey;
/* caller must provide at least one old/new */
@ -414,16 +415,27 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
if (new && sta && pairwise) {
/* Unicast rekey needs special handling. With Extended Key ID
* old is still NULL for the first rekey.
*/
ieee80211_pairwise_rekey(old, new);
}
if (old) {
idx = old->conf.keyidx;
ret = ieee80211_hw_key_replace(old, new, pairwise);
if (old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
ieee80211_key_disable_hw_accel(old);
if (new)
ret = ieee80211_key_enable_hw_accel(new);
}
} else {
/* new must be provided in case old is not */
idx = new->conf.keyidx;
if (!new->local->wowlan)
ret = ieee80211_key_enable_hw_accel(new);
else
ret = 0;
}
if (ret)

View File

@ -3148,6 +3148,19 @@ static bool ieee80211_twt_req_supported(const struct sta_info *sta,
IEEE80211_HE_MAC_CAP0_TWT_RES;
}
static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
struct ieee802_11_elems *elems)
{
bool twt = ieee80211_twt_req_supported(sta, elems);
if (sdata->vif.bss_conf.twt_requester != twt) {
sdata->vif.bss_conf.twt_requester = twt;
return BSS_CHANGED_TWT;
}
return 0;
}
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss,
struct ieee80211_mgmt *mgmt, size_t len)
@ -3330,8 +3343,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
sta);
bss_conf->he_support = sta->sta.he_cap.has_he;
bss_conf->twt_requester =
ieee80211_twt_req_supported(sta, &elems);
changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
} else {
bss_conf->he_support = false;
bss_conf->twt_requester = false;
@ -3991,6 +4003,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->sta_mtx);
sta = sta_info_get(sdata, bssid);
changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
if (ieee80211_config_bw(sdata, sta,
elems.ht_cap_elem, elems.ht_operation,
elems.vht_operation, elems.he_operation,
@ -4941,7 +4955,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
basic_rates = BIT(min_rate_index);
}
new_sta->sta.supp_rates[cbss->channel->band] = rates;
if (rates)
new_sta->sta.supp_rates[cbss->channel->band] = rates;
else
sdata_info(sdata,
"No rates found, keeping mandatory only\n");
sdata->vif.bss_conf.basic_rates = basic_rates;
/* cf. IEEE 802.11 9.2.12 */

View File

@ -202,6 +202,10 @@ static void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
roc->cookie, roc->chan,
GFP_KERNEL);
else
cfg80211_tx_mgmt_expired(&roc->sdata->wdev,
roc->mgmt_tx_cookie,
roc->chan, GFP_KERNEL);
list_del(&roc->list);
kfree(roc);

View File

@ -357,8 +357,10 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
break;
}
WARN_ONCE(i == sband->n_bitrates,
"no supported rates (0x%x) in rate_mask 0x%x with flags 0x%x\n",
"no supported rates for sta %pM (0x%x, band %d) in rate_mask 0x%x with flags 0x%x\n",
sta ? sta->addr : NULL,
sta ? sta->supp_rates[sband->band] : -1,
sband->band,
rate_mask, rate_flags);
info->control.rates[0].count =
@ -369,9 +371,8 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
}
bool rate_control_send_low(struct ieee80211_sta *pubsta,
void *priv_sta,
struct ieee80211_tx_rate_control *txrc)
static bool rate_control_send_low(struct ieee80211_sta *pubsta,
struct ieee80211_tx_rate_control *txrc)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
struct ieee80211_supported_band *sband = txrc->sband;
@ -379,7 +380,7 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
int mcast_rate;
bool use_basicrate = false;
if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
if (!pubsta || rc_no_data_or_no_ack_use_min(txrc)) {
__rate_control_send_low(txrc->hw, sband, pubsta, info,
txrc->rate_idx_mask);
@ -405,7 +406,6 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
}
return false;
}
EXPORT_SYMBOL(rate_control_send_low);
static bool rate_idx_match_legacy_mask(s8 *rate_idx, int n_bitrates, u32 mask)
{
@ -888,26 +888,29 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
int i;
if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
ista = &sta->sta;
priv_sta = sta->rate_ctrl_priv;
}
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
info->control.rates[i].idx = -1;
info->control.rates[i].flags = 0;
info->control.rates[i].count = 0;
}
if (rate_control_send_low(sta ? &sta->sta : NULL, txrc))
return;
if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL))
return;
if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
ista = &sta->sta;
priv_sta = sta->rate_ctrl_priv;
}
if (ista) {
spin_lock_bh(&sta->rate_ctrl_lock);
ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
spin_unlock_bh(&sta->rate_ctrl_lock);
} else {
ref->ops->get_rate(ref->priv, NULL, NULL, txrc);
rate_control_send_low(NULL, txrc);
}
if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_RC_TABLE))

View File

@ -340,10 +340,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
int delta;
int sampling_ratio;
/* management/no-ack frames do not use rate control */
if (rate_control_send_low(sta, priv_sta, txrc))
return;
/* check multi-rate-retry capabilities & adjust lookaround_rate */
mrr_capable = mp->has_mrr &&
!txrc->rts &&

View File

@ -1098,9 +1098,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct minstrel_priv *mp = priv;
int sample_idx;
if (rate_control_send_low(sta, priv_sta, txrc))
return;
if (!msp->is_ht)
return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);

View File

@ -3,7 +3,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018-2019 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -404,6 +404,47 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
for (i = 0; i < NUM_NL80211_BANDS; i++) {
u32 mandatory = 0;
int r;
if (!hw->wiphy->bands[i])
continue;
switch (i) {
case NL80211_BAND_2GHZ:
/*
* We use both here, even if we cannot really know for
* sure the station will support both, but the only use
* for this is when we don't know anything yet and send
* management frames, and then we'll pick the lowest
* possible rate anyway.
* If we don't include _G here, we cannot find a rate
* in P2P, and thus trigger the WARN_ONCE() in rate.c
*/
mandatory = IEEE80211_RATE_MANDATORY_B |
IEEE80211_RATE_MANDATORY_G;
break;
case NL80211_BAND_5GHZ:
mandatory = IEEE80211_RATE_MANDATORY_A;
break;
case NL80211_BAND_60GHZ:
WARN_ON(1);
mandatory = 0;
break;
}
for (r = 0; r < hw->wiphy->bands[i]->n_bitrates; r++) {
struct ieee80211_rate *rate;
rate = &hw->wiphy->bands[i]->bitrates[r];
if (!(rate->flags & mandatory))
continue;
sta->sta.supp_rates[i] |= BIT(r);
}
}
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {

View File

@ -859,6 +859,19 @@ int wiphy_register(struct wiphy *wiphy)
return -EINVAL;
}
for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
/*
* Validate we have a policy (can be explicitly set to
* VENDOR_CMD_RAW_DATA which is non-NULL) and also that
* we have at least one of doit/dumpit.
*/
if (WARN_ON(!rdev->wiphy.vendor_commands[i].policy))
return -EINVAL;
if (WARN_ON(!rdev->wiphy.vendor_commands[i].doit &&
!rdev->wiphy.vendor_commands[i].dumpit))
return -EINVAL;
}
#ifdef CONFIG_PM
if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
(!rdev->wiphy.wowlan->pattern_min_len ||

View File

@ -531,6 +531,10 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev);
struct cfg80211_internal_bss *
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *tmp,
bool signal_valid, unsigned long ts);
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
#else

View File

@ -304,8 +304,11 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
[NL80211_ATTR_MAC] = { .len = ETH_ALEN },
[NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
[NL80211_ATTR_MAC] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
[NL80211_ATTR_PREV_BSSID] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
@ -356,7 +359,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
[NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
[NL80211_ATTR_HT_CAPABILITY] = {
.type = NLA_EXACT_LEN_WARN,
.len = NL80211_HT_CAPABILITY_LEN
},
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
[NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
@ -386,7 +392,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
[NL80211_ATTR_PID] = { .type = NLA_U32 },
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
[NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
[NL80211_ATTR_PMKID] = {
.type = NLA_EXACT_LEN_WARN,
.len = WLAN_PMKID_LEN
},
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
@ -448,7 +457,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_WDEV] = { .type = NLA_U64 },
[NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
[NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
[NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
[NL80211_ATTR_VHT_CAPABILITY] = {
.type = NLA_EXACT_LEN_WARN,
.len = NL80211_VHT_CAPABILITY_LEN
},
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
[NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
@ -484,7 +496,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
[NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
.len = IEEE80211_QOS_MAP_LEN_MAX },
[NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
[NL80211_ATTR_MAC_HINT] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
[NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
@ -495,7 +510,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
[NL80211_ATTR_MAC_MASK] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
@ -507,15 +525,21 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
.len = VHT_MUMIMO_GROUPS_DATA_LEN
},
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
[NL80211_ATTR_BANDS] = { .type = NLA_U32 },
[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
[NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
.len = FILS_MAX_KEK_LEN },
[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
[NL80211_ATTR_FILS_NONCES] = {
.type = NLA_EXACT_LEN_WARN,
.len = 2 * FILS_NONCE_LEN
},
[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
[NL80211_ATTR_BSSID] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
.len = sizeof(struct nl80211_bss_select_rssi_adjust)
@ -528,7 +552,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
[NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
.len = FILS_ERP_MAX_RRK_LEN },
[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
[NL80211_ATTR_FILS_CACHE_ID] = { .type = NLA_EXACT_LEN_WARN, .len = 2 },
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
@ -547,6 +571,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_PEER_MEASUREMENTS] =
NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
[NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
.len = SAE_PASSWORD_MAX_LEN },
[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
};
/* policy for the key attributes */
@ -589,10 +616,13 @@ static const struct nla_policy
nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
[NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
[NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
[NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
[NL80211_WOWLAN_TCP_DST_MAC] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
[NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
[NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
[NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
.len = sizeof(struct nl80211_wowlan_tcp_data_seq)
},
@ -600,8 +630,8 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
.len = sizeof(struct nl80211_wowlan_tcp_data_token)
},
[NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
[NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
[NL80211_WOWLAN_TCP_WAKE_MASK] = { .type = NLA_MIN_LEN, .len = 1 },
};
#endif /* CONFIG_PM */
@ -619,9 +649,12 @@ nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
/* policy for GTK rekey offload attributes */
static const struct nla_policy
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
[NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
[NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
[NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
[NL80211_REKEY_DATA_KEK] = { .type = NLA_EXACT_LEN_WARN, .len = NL80211_KEK_LEN },
[NL80211_REKEY_DATA_KCK] = { .type = NLA_EXACT_LEN_WARN, .len = NL80211_KCK_LEN },
[NL80211_REKEY_DATA_REPLAY_CTR] = {
.type = NLA_EXACT_LEN_WARN,
.len = NL80211_REPLAY_CTR_LEN
},
};
static const struct nla_policy
@ -635,7 +668,10 @@ 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_BSSID] = {
.type = NLA_EXACT_LEN_WARN,
.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),
@ -667,7 +703,10 @@ nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
[NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = {
.type = NLA_EXACT_LEN_WARN,
.len = ETH_ALEN
},
[NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
[NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
[NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
@ -4057,7 +4096,7 @@ static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
.len = NL80211_MAX_SUPP_RATES },
[NL80211_TXRATE_HT] = { .type = NLA_BINARY,
.len = NL80211_MAX_SUPP_HT_RATES },
[NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
[NL80211_TXRATE_VHT] = { .type = NLA_EXACT_LEN_WARN, .len = sizeof(struct nl80211_txrate_vht)},
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
};
@ -4398,6 +4437,8 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
return true;
case NL80211_CMD_CONNECT:
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
!wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
auth_type == NL80211_AUTHTYPE_SAE)
return false;
@ -4588,6 +4629,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
return PTR_ERR(params.acl);
}
params.twt_responder =
nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
nl80211_calculate_ap_params(&params);
if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
@ -8700,7 +8744,8 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
static bool nl80211_valid_wpa_versions(u32 wpa_versions)
{
return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
NL80211_WPA_VERSION_2));
NL80211_WPA_VERSION_2 |
NL80211_WPA_VERSION_3));
}
static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
@ -8936,6 +8981,16 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
}
if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
if (!wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD))
return -EINVAL;
settings->sae_pwd =
nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
settings->sae_pwd_len =
nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
}
return 0;
}
@ -12618,6 +12673,29 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb,
return 0;
}
static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
struct nlattr *attr,
struct netlink_ext_ack *extack)
{
if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
if (attr->nla_type & NLA_F_NESTED) {
NL_SET_ERR_MSG_ATTR(extack, attr,
"unexpected nested data");
return -EINVAL;
}
return 0;
}
if (!(attr->nla_type & NLA_F_NESTED)) {
NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
return -EINVAL;
}
return nl80211_validate_nested(attr, vcmd->maxattr, vcmd->policy,
extack);
}
static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@ -12676,11 +12754,16 @@ static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
err = nl80211_vendor_check_policy(vcmd,
info->attrs[NL80211_ATTR_VENDOR_DATA],
info->extack);
if (err)
return err;
}
rdev->cur_cmd_info = info;
err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
data, len);
err = vcmd->doit(&rdev->wiphy, wdev, data, len);
rdev->cur_cmd_info = NULL;
return err;
}
@ -12767,6 +12850,13 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
err = nl80211_vendor_check_policy(
&(*rdev)->wiphy.vendor_commands[vcmd_idx],
attrbuf[NL80211_ATTR_VENDOR_DATA],
cb->extack);
if (err)
return err;
}
/* 0 is the first index - add 1 to parse only once */
@ -15035,7 +15125,9 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
return;
}
if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
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, bssid))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@ -15325,6 +15417,19 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
}
EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
struct ieee80211_channel *chan,
gfp_t gfp)
{
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
rdev, wdev, cookie, chan, 0, gfp);
}
EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp)
{

View File

@ -1092,17 +1092,17 @@ struct cfg80211_non_tx_bss {
};
/* Returned bss is reference counted and must be cleaned up appropriately. */
static struct cfg80211_internal_bss *
struct cfg80211_internal_bss *
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *tmp,
bool signal_valid)
bool signal_valid, unsigned long ts)
{
struct cfg80211_internal_bss *found = NULL;
if (WARN_ON(!tmp->pub.channel))
return NULL;
tmp->ts = jiffies;
tmp->ts = ts;
spin_lock_bh(&rdev->bss_lock);
@ -1425,7 +1425,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
jiffies);
if (!res)
return NULL;
@ -1842,7 +1843,8 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
jiffies);
if (!res)
return NULL;
@ -1972,6 +1974,27 @@ out:
}
EXPORT_SYMBOL(cfg80211_unlink_bss);
void cfg80211_bss_iter(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef,
void (*iter)(struct wiphy *wiphy,
struct cfg80211_bss *bss,
void *data),
void *iter_data)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct cfg80211_internal_bss *bss;
spin_lock_bh(&rdev->bss_lock);
list_for_each_entry(bss, &rdev->bss_list, list) {
if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel))
iter(wiphy, &bss->pub, iter_data);
}
spin_unlock_bh(&rdev->bss_lock);
}
EXPORT_SYMBOL(cfg80211_bss_iter);
#ifdef CONFIG_CFG80211_WEXT
static struct cfg80211_registered_device *
cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)

View File

@ -796,12 +796,36 @@ void cfg80211_connect_done(struct net_device *dev,
u8 *next;
if (params->bss) {
/* Make sure the bss entry provided by the driver is valid. */
struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
if (WARN_ON(list_empty(&ibss->list))) {
cfg80211_put_bss(wdev->wiphy, params->bss);
return;
if (list_empty(&ibss->list)) {
struct cfg80211_bss *found = NULL, *tmp = params->bss;
found = cfg80211_get_bss(wdev->wiphy, NULL,
params->bss->bssid,
wdev->ssid, wdev->ssid_len,
wdev->conn_bss_type,
IEEE80211_PRIVACY_ANY);
if (found) {
/* The same BSS is already updated so use it
* instead, as it has latest info.
*/
params->bss = found;
} else {
/* Update with BSS provided by driver, it will
* be freshly added and ref cnted, we can free
* the old one.
*
* signal_valid can be false, as we are not
* expecting the BSS to be found.
*
* keep the old timestamp to avoid confusion
*/
cfg80211_bss_update(rdev, ibss, false,
ibss->ts);
}
cfg80211_put_bss(wdev->wiphy, tmp);
}
}

View File

@ -2752,6 +2752,24 @@ TRACE_EVENT(cfg80211_ready_on_channel_expired,
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
);
TRACE_EVENT(cfg80211_tx_mgmt_expired,
TP_PROTO(struct wireless_dev *wdev, u64 cookie,
struct ieee80211_channel *chan),
TP_ARGS(wdev, cookie, chan),
TP_STRUCT__entry(
WDEV_ENTRY
__field(u64, cookie)
CHAN_ENTRY
),
TP_fast_assign(
WDEV_ASSIGN;
__entry->cookie = cookie;
CHAN_ASSIGN(chan);
),
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT,
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
);
TRACE_EVENT(cfg80211_new_sta,
TP_PROTO(struct net_device *netdev, const u8 *mac_addr,
struct station_info *sinfo),