A new set of changes:
* lots of small documentation fixes, from Jérôme Pouiller * beacon protection (BIGTK) support from Jouni Malinen * some initial code for TID configuration, from Tamizh chelvam * I reverted some new API before it's actually used, because it's wrong to mix controlled port and preauth * a few other cleanups/fixes -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl5UFlsACgkQB8qZga/f l8SwNQ//Y/dELGODumDxY03l/Bj/+XL7HYl3Yn+J8mt2mYPC3zjTjvcRJBApiAog 1Oyd75fd+EqjxDUT+ngN8uJLQ/yCVsdwfpZhwV7VanAOuLI9aYkIXnai/Qs96rj3 yDIlrBVsmfsaxf/2e9UmsLmeUSm7C5s1EzaAIwoRGvcUH0pbH9WYAXF1QV+8fmXa yoXuHV5Bv+wOW2xWqWJsFpoV109AW24pwJm0vlILcpFP/jno2GsRvwEpnC/GJhEA 4+jfEj0KlFkOewp0/HcqrUJp4yDEBhnhTTYgDL3hSWgKRVorKqY4/QmpKQCmpVQk Qrb6k+TrnLmKBQKdqfd+PKAEC9U/9Wjg0KLPyc9btBGFNSUG3QoDigzxxIvSlW6w 2vyanDW6780FTIi8sA7sq1cBLosIyoFG44YYwbMidVtxhBk1LMRvetNAOnAJeycp Abbp/A2EdvzM+ZMNMRwWlsgig6WkGY7jy/zpcmQUdALM+yT2o7D5ZwxE5pa2ggds jf0eER1vVCEpOL70swNSZbAnDNCzBzTN64GX9gQIjdVT+nMUYQXwuOgEmho1FshD bgZz4PcaOCCSTice9GYCC3C9OqXBsE2DyBwytYYzahyDiQH13Iz6wEq/+tIIjzCN KKRdD12TXaPobLwv5zI3kogJ1I4P1fa6RZYpkngLpMbQrQ7qiDI= =x0rf -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-net-next-2020-02-24' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== A new set of changes: * lots of small documentation fixes, from Jérôme Pouiller * beacon protection (BIGTK) support from Jouni Malinen * some initial code for TID configuration, from Tamizh chelvam * I reverted some new API before it's actually used, because it's wrong to mix controlled port and preauth * a few other cleanups/fixes ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
3b3e808cd8
|
@ -2947,6 +2947,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
|||
NL80211_FEATURE_DYNAMIC_SMPS |
|
||||
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
|
||||
|
||||
hw->wiphy->interface_modes = param->iftypes;
|
||||
|
||||
|
|
|
@ -72,12 +72,12 @@ struct wiphy;
|
|||
*
|
||||
* @IEEE80211_CHAN_DISABLED: This channel is disabled.
|
||||
* @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes
|
||||
* sending probe requests or beaconing.
|
||||
* sending probe requests or beaconing.
|
||||
* @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
|
||||
* @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
|
||||
* is not permitted.
|
||||
* is not permitted.
|
||||
* @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
|
||||
* is not permitted.
|
||||
* is not permitted.
|
||||
* @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel.
|
||||
* @IEEE80211_CHAN_NO_80MHZ: If the driver supports 80 MHz on the band,
|
||||
* this flag indicates that an 80 MHz channel cannot use this
|
||||
|
@ -626,6 +626,41 @@ struct cfg80211_chan_def {
|
|||
struct ieee80211_edmg edmg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cfg80211_tid_cfg - TID specific configuration
|
||||
* @config_override: Flag to notify driver to reset TID configuration
|
||||
* of the peer.
|
||||
* @tids: bitmap of TIDs to modify
|
||||
* @mask: bitmap of attributes indicating which parameter changed,
|
||||
* similar to &nl80211_tid_config_supp.
|
||||
* @noack: noack configuration value for the TID
|
||||
* @retry_long: retry count value
|
||||
* @retry_short: retry count value
|
||||
* @ampdu: Enable/Disable aggregation
|
||||
* @rtscts: Enable/Disable RTS/CTS
|
||||
*/
|
||||
struct cfg80211_tid_cfg {
|
||||
bool config_override;
|
||||
u8 tids;
|
||||
u32 mask;
|
||||
enum nl80211_tid_config noack;
|
||||
u8 retry_long, retry_short;
|
||||
enum nl80211_tid_config ampdu;
|
||||
enum nl80211_tid_config rtscts;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cfg80211_tid_config - TID configuration
|
||||
* @peer: Station's MAC address
|
||||
* @n_tid_conf: Number of TID specific configurations to be applied
|
||||
* @tid_conf: Configuration change info
|
||||
*/
|
||||
struct cfg80211_tid_config {
|
||||
const u8 *peer;
|
||||
u32 n_tid_conf;
|
||||
struct cfg80211_tid_cfg tid_conf[];
|
||||
};
|
||||
|
||||
/**
|
||||
* cfg80211_get_chandef_type - return old channel type from chandef
|
||||
* @chandef: the channel definition
|
||||
|
@ -1686,7 +1721,7 @@ struct mpath_info {
|
|||
* @basic_rates_len: number of basic rates
|
||||
* @ap_isolate: do not forward packets between connected stations
|
||||
* @ht_opmode: HT Operation mode
|
||||
* (u16 = opmode, -1 = do not change)
|
||||
* (u16 = opmode, -1 = do not change)
|
||||
* @p2p_ctwindow: P2P CT Window (-1 = no change)
|
||||
* @p2p_opp_ps: P2P opportunistic PS (-1 = no change)
|
||||
*/
|
||||
|
@ -2062,8 +2097,8 @@ struct cfg80211_bss_select_adjust {
|
|||
* @ie_len: length of ie in octets
|
||||
* @flags: bit field of flags controlling operation
|
||||
* @match_sets: sets of parameters to be matched for a scan result
|
||||
* entry to be considered valid and to be passed to the host
|
||||
* (others are filtered out).
|
||||
* entry to be considered valid and to be passed to the host
|
||||
* (others are filtered out).
|
||||
* If ommited, all results are passed.
|
||||
* @n_match_sets: number of match sets
|
||||
* @report_results: indicates that results were reported for this request
|
||||
|
@ -2456,7 +2491,7 @@ struct cfg80211_disassoc_request {
|
|||
* will be used in ht_capa. Un-supported values will be ignored.
|
||||
* @ht_capa_mask: The bits of ht_capa which are to be used.
|
||||
* @wep_keys: static WEP keys, if not NULL points to an array of
|
||||
* CFG80211_MAX_WEP_KEYS WEP keys
|
||||
* CFG80211_MAX_WEP_KEYS WEP keys
|
||||
* @wep_tx_key: key index (0..3) of the default TX static WEP key
|
||||
*/
|
||||
struct cfg80211_ibss_params {
|
||||
|
@ -3369,6 +3404,8 @@ struct cfg80211_update_owe_info {
|
|||
* @set_default_key: set the default key on an interface
|
||||
*
|
||||
* @set_default_mgmt_key: set the default management frame key on an interface
|
||||
|
||||
* @set_default_beacon_key: set the default Beacon frame key on an interface
|
||||
*
|
||||
* @set_rekey_data: give the data necessary for GTK rekeying to the driver
|
||||
*
|
||||
|
@ -3669,6 +3706,10 @@ struct cfg80211_update_owe_info {
|
|||
*
|
||||
* @probe_mesh_link: Probe direct Mesh peer's link quality by sending data frame
|
||||
* and overrule HWMP path selection algorithm.
|
||||
* @set_tid_config: TID specific configuration, this can be peer or BSS specific
|
||||
* This callback may sleep.
|
||||
* @reset_tid_config: Reset TID specific configuration for the peer, for the
|
||||
* given TIDs. This callback may sleep.
|
||||
*/
|
||||
struct cfg80211_ops {
|
||||
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
|
||||
|
@ -3702,6 +3743,9 @@ struct cfg80211_ops {
|
|||
int (*set_default_mgmt_key)(struct wiphy *wiphy,
|
||||
struct net_device *netdev,
|
||||
u8 key_index);
|
||||
int (*set_default_beacon_key)(struct wiphy *wiphy,
|
||||
struct net_device *netdev,
|
||||
u8 key_index);
|
||||
|
||||
int (*start_ap)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_ap_settings *settings);
|
||||
|
@ -3974,8 +4018,7 @@ struct cfg80211_ops {
|
|||
int (*tx_control_port)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const u8 *src,
|
||||
const __be16 proto,
|
||||
const u8 *dest, const __be16 proto,
|
||||
const bool noencrypt);
|
||||
|
||||
int (*get_ftm_responder_stats)(struct wiphy *wiphy,
|
||||
|
@ -3990,6 +4033,10 @@ struct cfg80211_ops {
|
|||
struct cfg80211_update_owe_info *owe_info);
|
||||
int (*probe_mesh_link)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len);
|
||||
int (*set_tid_config)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_tid_config *tid_conf);
|
||||
int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u8 tids);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -4427,7 +4474,7 @@ struct wiphy_iftype_akm_suites {
|
|||
* note that if your driver uses wiphy_apply_custom_regulatory()
|
||||
* the reg_notifier's request can be passed as NULL
|
||||
* @regd: the driver's regulatory domain, if one was requested via
|
||||
* the regulatory_hint() API. This can be used by the driver
|
||||
* the regulatory_hint() API. This can be used by the driver
|
||||
* on the reg_notifier() if it chooses to ignore future
|
||||
* regulatory domain changes caused by other drivers.
|
||||
* @signal_type: signal type reported in &struct cfg80211_bss.
|
||||
|
@ -4463,10 +4510,11 @@ struct wiphy_iftype_akm_suites {
|
|||
* the same number of arbitrary MAC addresses.
|
||||
* @registered: protects ->resume and ->suspend sysfs callbacks against
|
||||
* unregister hardware
|
||||
* @debugfsdir: debugfs directory used for this wiphy, will be renamed
|
||||
* automatically on wiphy renames
|
||||
* @dev: (virtual) struct device for this wiphy
|
||||
* @registered: helps synchronize suspend/resume with wiphy unregister
|
||||
* @debugfsdir: debugfs directory used for this wiphy (ieee80211/<wiphyname>).
|
||||
* It will be renamed automatically on wiphy renames
|
||||
* @dev: (virtual) struct device for this wiphy. The item in
|
||||
* /sys/class/ieee80211/ points to this. You need use set_wiphy_dev()
|
||||
* (see below).
|
||||
* @wext: wireless extension handlers
|
||||
* @priv: driver private data (sized according to wiphy_new() parameter)
|
||||
* @interface_modes: bitmask of interfaces types valid for this wiphy,
|
||||
|
@ -4577,12 +4625,6 @@ struct wiphy_iftype_akm_suites {
|
|||
* and probe responses. This value should be set if the driver
|
||||
* wishes to limit the number of csa counters. Default (0) means
|
||||
* infinite.
|
||||
* @max_adj_channel_rssi_comp: max offset of between the channel on which the
|
||||
* frame was sent and the channel on which the frame was heard for which
|
||||
* the reported rssi is still valid. If a driver is able to compensate the
|
||||
* low rssi when a frame is heard on different channel, then it should set
|
||||
* this variable to the maximal offset for which it can compensate.
|
||||
* This value should be set in MHz.
|
||||
* @bss_select_support: bitmask indicating the BSS selection criteria supported
|
||||
* by the driver in the .connect() callback. The bit position maps to the
|
||||
* attribute indices defined in &enum nl80211_bss_select_attr.
|
||||
|
@ -4602,11 +4644,19 @@ struct wiphy_iftype_akm_suites {
|
|||
* @support_mbssid must be set for this to have any effect.
|
||||
*
|
||||
* @pmsr_capa: peer measurement capabilities
|
||||
*
|
||||
* @tid_config_support: describes the per-TID config support that the
|
||||
* device has
|
||||
* @tid_config_support.vif: bitmap of attributes (configurations)
|
||||
* supported by the driver for each vif
|
||||
* @tid_config_support.peer: bitmap of attributes (configurations)
|
||||
* supported by the driver for each peer
|
||||
* @tid_config_support.max_retry: maximum supported retry count for
|
||||
* long/short retry configuration
|
||||
*/
|
||||
struct wiphy {
|
||||
/* assign these fields before you register the wiphy */
|
||||
|
||||
/* permanent MAC address(es) */
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
u8 addr_mask[ETH_ALEN];
|
||||
|
||||
|
@ -4673,11 +4723,6 @@ struct wiphy {
|
|||
u32 available_antennas_tx;
|
||||
u32 available_antennas_rx;
|
||||
|
||||
/*
|
||||
* Bitmap of supported protocols for probe response offloading
|
||||
* see &enum nl80211_probe_resp_offload_support_attr. Only valid
|
||||
* when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set.
|
||||
*/
|
||||
u32 probe_resp_offload;
|
||||
|
||||
const u8 *extended_capabilities, *extended_capabilities_mask;
|
||||
|
@ -4686,16 +4731,10 @@ struct wiphy {
|
|||
const struct wiphy_iftype_ext_capab *iftype_ext_capab;
|
||||
unsigned int num_iftype_ext_capab;
|
||||
|
||||
/* If multiple wiphys are registered and you're handed e.g.
|
||||
* a regular netdev with assigned ieee80211_ptr, you won't
|
||||
* know whether it points to a wiphy your driver has registered
|
||||
* or not. Assign this to something global to your driver to
|
||||
* help determine whether you own this wiphy or not. */
|
||||
const void *privid;
|
||||
|
||||
struct ieee80211_supported_band *bands[NUM_NL80211_BANDS];
|
||||
|
||||
/* Lets us get back the wiphy on the callback */
|
||||
void (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request);
|
||||
|
||||
|
@ -4703,14 +4742,10 @@ struct wiphy {
|
|||
|
||||
const struct ieee80211_regdomain __rcu *regd;
|
||||
|
||||
/* the item in /sys/class/ieee80211/ points to this,
|
||||
* you need use set_wiphy_dev() (see below) */
|
||||
struct device dev;
|
||||
|
||||
/* protects ->resume, ->suspend sysfs callbacks against unregister hw */
|
||||
bool registered;
|
||||
|
||||
/* dir in debugfs: ieee80211/<wiphyname> */
|
||||
struct dentry *debugfsdir;
|
||||
|
||||
const struct ieee80211_ht_cap *ht_capa_mod_mask;
|
||||
|
@ -4718,7 +4753,6 @@ struct wiphy {
|
|||
|
||||
struct list_head wdev_list;
|
||||
|
||||
/* the network namespace this phy lives in currently */
|
||||
possible_net_t _net;
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
|
@ -4734,7 +4768,6 @@ struct wiphy {
|
|||
u16 max_ap_assoc_sta;
|
||||
|
||||
u8 max_num_csa_counters;
|
||||
u8 max_adj_channel_rssi_comp;
|
||||
|
||||
u32 bss_select_support;
|
||||
|
||||
|
@ -4751,6 +4784,13 @@ struct wiphy {
|
|||
|
||||
const struct cfg80211_pmsr_capabilities *pmsr_capa;
|
||||
|
||||
struct {
|
||||
u64 peer, vif;
|
||||
u8 max_retry;
|
||||
} tid_config_support;
|
||||
|
||||
u8 max_data_retry_count;
|
||||
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
|
@ -5526,9 +5566,9 @@ void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr);
|
|||
* @wiphy: the wireless device giving the hint (used only for reporting
|
||||
* conflicts)
|
||||
* @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
|
||||
* should be in. If @rd is set this should be NULL. Note that if you
|
||||
* set this to NULL you should still set rd->alpha2 to some accepted
|
||||
* alpha2.
|
||||
* should be in. If @rd is set this should be NULL. Note that if you
|
||||
* set this to NULL you should still set rd->alpha2 to some accepted
|
||||
* alpha2.
|
||||
*
|
||||
* Wireless drivers can use this function to hint to the wireless core
|
||||
* what it believes should be the current regulatory domain by
|
||||
|
|
|
@ -3776,6 +3776,9 @@ enum ieee80211_reconfig_type {
|
|||
*
|
||||
* @start_pmsr: start peer measurement (e.g. FTM) (this call can sleep)
|
||||
* @abort_pmsr: abort peer measurement (this call can sleep)
|
||||
* @set_tid_config: Apply TID specific configurations. This callback may sleep.
|
||||
* @reset_tid_config: Reset TID specific configuration for the peer.
|
||||
* This callback may sleep.
|
||||
*/
|
||||
struct ieee80211_ops {
|
||||
void (*tx)(struct ieee80211_hw *hw,
|
||||
|
@ -4080,6 +4083,13 @@ struct ieee80211_ops {
|
|||
struct cfg80211_pmsr_request *request);
|
||||
void (*abort_pmsr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct cfg80211_pmsr_request *request);
|
||||
int (*set_tid_config)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct cfg80211_tid_config *tid_conf);
|
||||
int (*reset_tid_config)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u8 tids);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -264,6 +264,29 @@
|
|||
* %NL80211_ATTR_VLAN_ID.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: TID configuration
|
||||
*
|
||||
* TID config support can be checked in the %NL80211_ATTR_TID_CONFIG
|
||||
* attribute given in wiphy capabilities.
|
||||
*
|
||||
* The necessary configuration parameters are mentioned in
|
||||
* &enum nl80211_tid_config_attr and it will be passed to the
|
||||
* %NL80211_CMD_SET_TID_CONFIG command in %NL80211_ATTR_TID_CONFIG.
|
||||
*
|
||||
* If the configuration needs to be applied for specific peer then the MAC
|
||||
* address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the
|
||||
* configuration will be applied for all the connected peers in the vif except
|
||||
* any peers that have peer specific configuration for the TID by default; if
|
||||
* the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer specific values
|
||||
* will be overwritten.
|
||||
*
|
||||
* All this configuration is valid only for STA's current connection
|
||||
* i.e. the configuration will be reset to default when the STA connects back
|
||||
* after disconnection/roaming, and this configuration will be cleared when
|
||||
* the interface goes down.
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum nl80211_commands - supported nl80211 commands
|
||||
*
|
||||
|
@ -1039,14 +1062,11 @@
|
|||
* a control port frame and as a notification that a control port frame
|
||||
* has been received. %NL80211_ATTR_FRAME is used to specify the
|
||||
* frame contents. The frame is the raw EAPoL data, without ethernet or
|
||||
* 802.11 headers. An optional %NL80211_ATTR_SRC_MAC can be used to send
|
||||
* pre-auth frames to STAs on behalf of other APs.
|
||||
* 802.11 headers.
|
||||
* When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
|
||||
* %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
|
||||
* indicating the protocol type of the received frame; whether the frame
|
||||
* was received unencrypted and the MAC address of the peer respectively.
|
||||
* %NL80211_ATTR_DST_MAC can be used to forward pre-auth frames in
|
||||
* userspace while using AP mode.
|
||||
*
|
||||
* @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
|
||||
*
|
||||
|
@ -1128,6 +1148,9 @@
|
|||
* peer MAC address and %NL80211_ATTR_FRAME is used to specify the frame
|
||||
* content. The frame is ethernet data.
|
||||
*
|
||||
* @NL80211_CMD_SET_TID_CONFIG: Data frame TID specific configuration
|
||||
* is passed using %NL80211_ATTR_TID_CONFIG attribute.
|
||||
*
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
*/
|
||||
|
@ -1352,6 +1375,8 @@ enum nl80211_commands {
|
|||
|
||||
NL80211_CMD_PROBE_MESH_LINK,
|
||||
|
||||
NL80211_CMD_SET_TID_CONFIG,
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
|
@ -2412,8 +2437,10 @@ enum nl80211_commands {
|
|||
* %NL80211_ATTR_AKM_SUITES are default capabilities if AKM suites not
|
||||
* advertised for a specific interface type.
|
||||
*
|
||||
* @NL80211_ATTR_SRC_MAC: MAC address used in control port over nl80211 transmit
|
||||
* @NL80211_ATTR_DST_MAC: MAC address used in control port over nl80211 receive
|
||||
* @NL80211_ATTR_TID_CONFIG: TID specific configuration in a
|
||||
* nested attribute with &enum nl80211_tid_config_attr sub-attributes;
|
||||
* on output (in wiphy attributes) it contains only the feature sub-
|
||||
* attributes.
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
|
@ -2883,8 +2910,7 @@ enum nl80211_attrs {
|
|||
|
||||
NL80211_ATTR_IFTYPE_AKM_SUITES,
|
||||
|
||||
NL80211_ATTR_SRC_MAC,
|
||||
NL80211_ATTR_DST_MAC,
|
||||
NL80211_ATTR_TID_CONFIG,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
|
@ -4559,6 +4585,7 @@ enum nl80211_key_default_types {
|
|||
* See &enum nl80211_key_default_types.
|
||||
* @NL80211_KEY_MODE: the mode from enum nl80211_key_mode.
|
||||
* Defaults to @NL80211_KEY_RX_TX.
|
||||
* @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key
|
||||
*
|
||||
* @__NL80211_KEY_AFTER_LAST: internal
|
||||
* @NL80211_KEY_MAX: highest key attribute
|
||||
|
@ -4574,6 +4601,7 @@ enum nl80211_key_attributes {
|
|||
NL80211_KEY_TYPE,
|
||||
NL80211_KEY_DEFAULT_TYPES,
|
||||
NL80211_KEY_MODE,
|
||||
NL80211_KEY_DEFAULT_BEACON,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_KEY_AFTER_LAST,
|
||||
|
@ -4729,6 +4757,69 @@ enum nl80211_tx_power_setting {
|
|||
NL80211_TX_POWER_FIXED,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_tid_config - TID config state
|
||||
* @NL80211_TID_CONFIG_ENABLE: Enable config for the TID
|
||||
* @NL80211_TID_CONFIG_DISABLE: Disable config for the TID
|
||||
*/
|
||||
enum nl80211_tid_config {
|
||||
NL80211_TID_CONFIG_ENABLE,
|
||||
NL80211_TID_CONFIG_DISABLE,
|
||||
};
|
||||
|
||||
/* enum nl80211_tid_config_attr - TID specific configuration.
|
||||
* @NL80211_TID_CONFIG_ATTR_PAD: pad attribute for 64-bit values
|
||||
* @NL80211_TID_CONFIG_ATTR_VIF_SUPP: a bitmap (u64) of attributes supported
|
||||
* for per-vif configuration; doesn't list the ones that are generic
|
||||
* (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
|
||||
* @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
|
||||
* per peer instead.
|
||||
* @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if no peer
|
||||
* is selected, if set indicates that the new configuration overrides
|
||||
* all previous peer configurations, otherwise previous peer specific
|
||||
* configurations should be left untouched. If peer is selected then
|
||||
* it will reset particular TID configuration of that peer and it will
|
||||
* not accept other TID config attributes along with peer.
|
||||
* @NL80211_TID_CONFIG_ATTR_TIDS: a bitmask value of TIDs (bit 0 to 7)
|
||||
* Its type is u16.
|
||||
* @NL80211_TID_CONFIG_ATTR_NOACK: Configure ack policy for the TID.
|
||||
* specified in %NL80211_TID_CONFIG_ATTR_TID. see %enum nl80211_tid_config.
|
||||
* Its type is u8.
|
||||
* @NL80211_TID_CONFIG_ATTR_RETRY_SHORT: Number of retries used with data frame
|
||||
* transmission, user-space sets this configuration in
|
||||
* &NL80211_CMD_SET_TID_CONFIG. It is u8 type, min value is 1 and
|
||||
* the max value is advertised by the driver in this attribute on
|
||||
* output in wiphy capabilities.
|
||||
* @NL80211_TID_CONFIG_ATTR_RETRY_LONG: Number of retries used with data frame
|
||||
* transmission, user-space sets this configuration in
|
||||
* &NL80211_CMD_SET_TID_CONFIG. Its type is u8, min value is 1 and
|
||||
* the max value is advertised by the driver in this attribute on
|
||||
* output in wiphy capabilities.
|
||||
* @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable aggregation for the TIDs
|
||||
* specified in %NL80211_TID_CONFIG_ATTR_TIDS. Its type is u8, using
|
||||
* the values from &nl80211_tid_config.
|
||||
* @NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL: Enable/Disable RTS_CTS for the TIDs
|
||||
* specified in %NL80211_TID_CONFIG_ATTR_TIDS. It is u8 type, using
|
||||
* the values from &nl80211_tid_config.
|
||||
*/
|
||||
enum nl80211_tid_config_attr {
|
||||
__NL80211_TID_CONFIG_ATTR_INVALID,
|
||||
NL80211_TID_CONFIG_ATTR_PAD,
|
||||
NL80211_TID_CONFIG_ATTR_VIF_SUPP,
|
||||
NL80211_TID_CONFIG_ATTR_PEER_SUPP,
|
||||
NL80211_TID_CONFIG_ATTR_OVERRIDE,
|
||||
NL80211_TID_CONFIG_ATTR_TIDS,
|
||||
NL80211_TID_CONFIG_ATTR_NOACK,
|
||||
NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
|
||||
NL80211_TID_CONFIG_ATTR_RETRY_LONG,
|
||||
NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
|
||||
NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_TID_CONFIG_ATTR_AFTER_LAST,
|
||||
NL80211_TID_CONFIG_ATTR_MAX = __NL80211_TID_CONFIG_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_packet_pattern_attr - packet pattern attribute
|
||||
* @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
|
||||
|
@ -5548,9 +5639,8 @@ enum nl80211_feature_flags {
|
|||
* feature, which prevents bufferbloat by using the expected transmission
|
||||
* time to limit the amount of data buffered in the hardware.
|
||||
*
|
||||
* @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_MAC_ADDRS: The driver
|
||||
* can use src and dst MAC addresses with control port over nl80211 rx
|
||||
* and tx operations.
|
||||
* @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
|
||||
* and can receive key configuration for BIGTK using key indexes 6 and 7.
|
||||
*
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
|
@ -5599,7 +5689,7 @@ enum nl80211_ext_feature_index {
|
|||
NL80211_EXT_FEATURE_SAE_OFFLOAD,
|
||||
NL80211_EXT_FEATURE_VLAN_OFFLOAD,
|
||||
NL80211_EXT_FEATURE_AQL,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_MAC_ADDRS,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
|
|
|
@ -26,12 +26,20 @@ void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
|
|||
{
|
||||
SHASH_DESC_ON_STACK(desc, tfm);
|
||||
u8 out[AES_BLOCK_SIZE];
|
||||
const __le16 *fc;
|
||||
|
||||
desc->tfm = tfm;
|
||||
|
||||
crypto_shash_init(desc);
|
||||
crypto_shash_update(desc, aad, AAD_LEN);
|
||||
crypto_shash_update(desc, data, data_len - CMAC_TLEN);
|
||||
fc = (const __le16 *)aad;
|
||||
if (ieee80211_is_beacon(*fc)) {
|
||||
/* mask Timestamp field to zero */
|
||||
crypto_shash_update(desc, zero, 8);
|
||||
crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN);
|
||||
} else {
|
||||
crypto_shash_update(desc, data, data_len - CMAC_TLEN);
|
||||
}
|
||||
crypto_shash_finup(desc, zero, CMAC_TLEN, out);
|
||||
|
||||
memcpy(mic, out, CMAC_TLEN);
|
||||
|
@ -41,12 +49,21 @@ void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
|
|||
const u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
SHASH_DESC_ON_STACK(desc, tfm);
|
||||
const __le16 *fc;
|
||||
|
||||
desc->tfm = tfm;
|
||||
|
||||
crypto_shash_init(desc);
|
||||
crypto_shash_update(desc, aad, AAD_LEN);
|
||||
crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
|
||||
fc = (const __le16 *)aad;
|
||||
if (ieee80211_is_beacon(*fc)) {
|
||||
/* mask Timestamp field to zero */
|
||||
crypto_shash_update(desc, zero, 8);
|
||||
crypto_shash_update(desc, data + 8,
|
||||
data_len - 8 - CMAC_TLEN_256);
|
||||
} else {
|
||||
crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
|
||||
}
|
||||
crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
const u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
struct scatterlist sg[4];
|
||||
struct scatterlist sg[5];
|
||||
u8 *zero, *__aad, iv[AES_BLOCK_SIZE];
|
||||
struct aead_request *aead_req;
|
||||
int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
const __le16 *fc;
|
||||
|
||||
if (data_len < GMAC_MIC_LEN)
|
||||
return -EINVAL;
|
||||
|
@ -33,11 +34,22 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
|||
__aad = zero + GMAC_MIC_LEN;
|
||||
memcpy(__aad, aad, GMAC_AAD_LEN);
|
||||
|
||||
sg_init_table(sg, 4);
|
||||
sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
|
||||
sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[2], zero, GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[3], mic, GMAC_MIC_LEN);
|
||||
fc = (const __le16 *)aad;
|
||||
if (ieee80211_is_beacon(*fc)) {
|
||||
/* mask Timestamp field to zero */
|
||||
sg_init_table(sg, 5);
|
||||
sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
|
||||
sg_set_buf(&sg[1], zero, 8);
|
||||
sg_set_buf(&sg[2], data + 8, data_len - 8 - GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[3], zero, GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[4], mic, GMAC_MIC_LEN);
|
||||
} else {
|
||||
sg_init_table(sg, 4);
|
||||
sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
|
||||
sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[2], zero, GMAC_MIC_LEN);
|
||||
sg_set_buf(&sg[3], mic, GMAC_MIC_LEN);
|
||||
}
|
||||
|
||||
memcpy(iv, nonce, GMAC_NONCE_LEN);
|
||||
memset(iv + GMAC_NONCE_LEN, 0, sizeof(iv) - GMAC_NONCE_LEN);
|
||||
|
|
|
@ -568,7 +568,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
|
|||
if (pairwise && key_idx < NUM_DEFAULT_KEYS)
|
||||
key = rcu_dereference(sta->ptk[key_idx]);
|
||||
else if (!pairwise &&
|
||||
key_idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
|
||||
key_idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS)
|
||||
key = rcu_dereference(sta->gtk[key_idx]);
|
||||
} else
|
||||
key = rcu_dereference(sdata->keys[key_idx]);
|
||||
|
@ -680,6 +681,17 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
u8 key_idx)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
ieee80211_set_default_beacon_key(sdata, key_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sta_set_rate_info_tx(struct sta_info *sta,
|
||||
const struct ieee80211_tx_rate *rate,
|
||||
struct rate_info *rinfo)
|
||||
|
@ -3874,6 +3886,60 @@ ieee80211_abort_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
|
|||
return drv_abort_pmsr(local, sdata, request);
|
||||
}
|
||||
|
||||
static int ieee80211_set_tid_config(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_tid_config *tid_conf)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sta_info *sta;
|
||||
int ret;
|
||||
|
||||
if (!sdata->local->ops->set_tid_config)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!tid_conf->peer)
|
||||
return drv_set_tid_config(sdata->local, sdata, NULL, tid_conf);
|
||||
|
||||
mutex_lock(&sdata->local->sta_mtx);
|
||||
sta = sta_info_get_bss(sdata, tid_conf->peer);
|
||||
if (!sta) {
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = drv_set_tid_config(sdata->local, sdata, &sta->sta, tid_conf);
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ieee80211_reset_tid_config(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *peer, u8 tid)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sta_info *sta;
|
||||
int ret;
|
||||
|
||||
if (!sdata->local->ops->reset_tid_config)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!peer)
|
||||
return drv_reset_tid_config(sdata->local, sdata, NULL, tid);
|
||||
|
||||
mutex_lock(&sdata->local->sta_mtx);
|
||||
sta = sta_info_get_bss(sdata, peer);
|
||||
if (!sta) {
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tid);
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
|
@ -3885,6 +3951,7 @@ const struct cfg80211_ops mac80211_config_ops = {
|
|||
.get_key = ieee80211_get_key,
|
||||
.set_default_key = ieee80211_config_default_key,
|
||||
.set_default_mgmt_key = ieee80211_config_default_mgmt_key,
|
||||
.set_default_beacon_key = ieee80211_config_default_beacon_key,
|
||||
.start_ap = ieee80211_start_ap,
|
||||
.change_beacon = ieee80211_change_beacon,
|
||||
.stop_ap = ieee80211_stop_ap,
|
||||
|
@ -3973,4 +4040,6 @@ const struct cfg80211_ops mac80211_config_ops = {
|
|||
.start_pmsr = ieee80211_start_pmsr,
|
||||
.abort_pmsr = ieee80211_abort_pmsr,
|
||||
.probe_mesh_link = ieee80211_probe_mesh_link,
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
};
|
||||
|
|
|
@ -433,6 +433,37 @@ void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sda
|
|||
sdata->debugfs.default_mgmt_key = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_debugfs_key_add_beacon_default(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
char buf[50];
|
||||
struct ieee80211_key *key;
|
||||
|
||||
if (!sdata->vif.debugfs_dir)
|
||||
return;
|
||||
|
||||
key = key_mtx_dereference(sdata->local,
|
||||
sdata->default_beacon_key);
|
||||
if (key) {
|
||||
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
||||
sdata->debugfs.default_beacon_key =
|
||||
debugfs_create_symlink("default_beacon_key",
|
||||
sdata->vif.debugfs_dir, buf);
|
||||
} else {
|
||||
ieee80211_debugfs_key_remove_beacon_default(sdata);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_debugfs_key_remove_beacon_default(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
if (!sdata)
|
||||
return;
|
||||
|
||||
debugfs_remove(sdata->debugfs.default_beacon_key);
|
||||
sdata->debugfs.default_beacon_key = NULL;
|
||||
}
|
||||
|
||||
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,10 @@ void ieee80211_debugfs_key_add_mgmt_default(
|
|||
struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_debugfs_key_remove_mgmt_default(
|
||||
struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_debugfs_key_add_beacon_default(
|
||||
struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_debugfs_key_remove_beacon_default(
|
||||
struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
|
||||
struct sta_info *sta);
|
||||
#else
|
||||
|
@ -26,6 +30,12 @@ static inline void ieee80211_debugfs_key_add_mgmt_default(
|
|||
static inline void ieee80211_debugfs_key_remove_mgmt_default(
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{}
|
||||
static inline void ieee80211_debugfs_key_add_beacon_default(
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{}
|
||||
static inline void ieee80211_debugfs_key_remove_beacon_default(
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{}
|
||||
static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
|
||||
struct sta_info *sta)
|
||||
{}
|
||||
|
|
|
@ -1358,4 +1358,31 @@ static inline void drv_del_nan_func(struct ieee80211_local *local,
|
|||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
static inline int drv_set_tid_config(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta *sta,
|
||||
struct cfg80211_tid_config *tid_conf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta,
|
||||
tid_conf);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int drv_reset_tid_config(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta *sta, u8 tid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tid);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
|
|
|
@ -901,10 +901,13 @@ struct ieee80211_sub_if_data {
|
|||
/* bit field of ACM bits (BIT(802.1D tag)) */
|
||||
u8 wmm_acm;
|
||||
|
||||
struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
|
||||
struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS +
|
||||
NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS];
|
||||
struct ieee80211_key __rcu *default_unicast_key;
|
||||
struct ieee80211_key __rcu *default_multicast_key;
|
||||
struct ieee80211_key __rcu *default_mgmt_key;
|
||||
struct ieee80211_key __rcu *default_beacon_key;
|
||||
|
||||
u16 sequence_number;
|
||||
__be16 control_port_protocol;
|
||||
|
@ -978,6 +981,7 @@ struct ieee80211_sub_if_data {
|
|||
struct dentry *default_unicast_key;
|
||||
struct dentry *default_multicast_key;
|
||||
struct dentry *default_mgmt_key;
|
||||
struct dentry *default_beacon_key;
|
||||
} debugfs;
|
||||
#endif
|
||||
|
||||
|
@ -1792,8 +1796,7 @@ void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
|
|||
void ieee80211_clear_fast_xmit(struct sta_info *sta);
|
||||
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const u8 *src, __be16 proto,
|
||||
bool unencrypted);
|
||||
const u8 *dest, __be16 proto, bool unencrypted);
|
||||
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len);
|
||||
|
||||
|
|
|
@ -407,6 +407,31 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
|||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
__ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata, int idx)
|
||||
{
|
||||
struct ieee80211_key *key = NULL;
|
||||
|
||||
assert_key_lock(sdata->local);
|
||||
|
||||
if (idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS &&
|
||||
idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS)
|
||||
key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
|
||||
|
||||
rcu_assign_pointer(sdata->default_beacon_key, key);
|
||||
|
||||
ieee80211_debugfs_key_update_default(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata,
|
||||
int idx)
|
||||
{
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
__ieee80211_set_default_beacon_key(sdata, idx);
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
||||
static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
bool pairwise,
|
||||
|
@ -415,7 +440,7 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
int idx;
|
||||
int ret = 0;
|
||||
bool defunikey, defmultikey, defmgmtkey;
|
||||
bool defunikey, defmultikey, defmgmtkey, defbeaconkey;
|
||||
|
||||
/* caller must provide at least one old/new */
|
||||
if (WARN_ON(!new && !old))
|
||||
|
@ -480,6 +505,9 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
defmgmtkey = old &&
|
||||
old == key_mtx_dereference(sdata->local,
|
||||
sdata->default_mgmt_key);
|
||||
defbeaconkey = old &&
|
||||
old == key_mtx_dereference(sdata->local,
|
||||
sdata->default_beacon_key);
|
||||
|
||||
if (defunikey && !new)
|
||||
__ieee80211_set_default_key(sdata, -1, true, false);
|
||||
|
@ -487,6 +515,8 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
__ieee80211_set_default_key(sdata, -1, false, true);
|
||||
if (defmgmtkey && !new)
|
||||
__ieee80211_set_default_mgmt_key(sdata, -1);
|
||||
if (defbeaconkey && !new)
|
||||
__ieee80211_set_default_beacon_key(sdata, -1);
|
||||
|
||||
rcu_assign_pointer(sdata->keys[idx], new);
|
||||
if (defunikey && new)
|
||||
|
@ -498,6 +528,9 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
if (defmgmtkey && new)
|
||||
__ieee80211_set_default_mgmt_key(sdata,
|
||||
new->conf.keyidx);
|
||||
if (defbeaconkey && new)
|
||||
__ieee80211_set_default_beacon_key(sdata,
|
||||
new->conf.keyidx);
|
||||
}
|
||||
|
||||
if (old)
|
||||
|
@ -515,7 +548,9 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
struct ieee80211_key *key;
|
||||
int i, j, err;
|
||||
|
||||
if (WARN_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS))
|
||||
if (WARN_ON(idx < 0 ||
|
||||
idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
|
||||
|
@ -978,6 +1013,7 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,
|
|||
sdata->crypto_tx_tailroom_pending_dec = 0;
|
||||
|
||||
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
||||
ieee80211_debugfs_key_remove_beacon_default(sdata);
|
||||
|
||||
list_for_each_entry_safe(key, tmp, &sdata->key_list, list) {
|
||||
ieee80211_key_replace(key->sdata, key->sta,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#define NUM_DEFAULT_KEYS 4
|
||||
#define NUM_DEFAULT_MGMT_KEYS 2
|
||||
#define NUM_DEFAULT_BEACON_KEYS 2
|
||||
#define INVALID_PTK_KEYIDX 2 /* Keyidx always pointing to a NULL key for PTK */
|
||||
|
||||
struct ieee80211_local;
|
||||
|
@ -153,6 +154,8 @@ void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
|
|||
bool uni, bool multi);
|
||||
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
||||
int idx);
|
||||
void ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata,
|
||||
int idx);
|
||||
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata,
|
||||
bool force_synchronize);
|
||||
void ieee80211_free_sta_keys(struct ieee80211_local *local,
|
||||
|
|
|
@ -589,8 +589,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
|||
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_MAC_ADDRS);
|
||||
|
||||
if (!ops->hw_scan) {
|
||||
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
|
||||
|
|
|
@ -983,7 +983,8 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
|
|||
if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
|
||||
return -1;
|
||||
|
||||
if (!ieee80211_is_robust_mgmt_frame(skb))
|
||||
if (!ieee80211_is_robust_mgmt_frame(skb) &&
|
||||
!ieee80211_is_beacon(hdr->frame_control))
|
||||
return -1; /* not a robust management frame */
|
||||
|
||||
mmie = (struct ieee80211_mmie *)
|
||||
|
@ -1868,6 +1869,41 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|||
return RX_CONTINUE;
|
||||
} /* ieee80211_rx_h_sta_process */
|
||||
|
||||
static struct ieee80211_key *
|
||||
ieee80211_rx_get_bigtk(struct ieee80211_rx_data *rx, int idx)
|
||||
{
|
||||
struct ieee80211_key *key = NULL;
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
int idx2;
|
||||
|
||||
/* Make sure key gets set if either BIGTK key index is set so that
|
||||
* ieee80211_drop_unencrypted_mgmt() can properly drop both unprotected
|
||||
* Beacon frames and Beacon frames that claim to use another BIGTK key
|
||||
* index (i.e., a key that we do not have).
|
||||
*/
|
||||
|
||||
if (idx < 0) {
|
||||
idx = NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
|
||||
idx2 = idx + 1;
|
||||
} else {
|
||||
if (idx == NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
|
||||
idx2 = idx + 1;
|
||||
else
|
||||
idx2 = idx - 1;
|
||||
}
|
||||
|
||||
if (rx->sta)
|
||||
key = rcu_dereference(rx->sta->gtk[idx]);
|
||||
if (!key)
|
||||
key = rcu_dereference(sdata->keys[idx]);
|
||||
if (!key && rx->sta)
|
||||
key = rcu_dereference(rx->sta->gtk[idx2]);
|
||||
if (!key)
|
||||
key = rcu_dereference(sdata->keys[idx2]);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
|
@ -1885,17 +1921,18 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
|||
/*
|
||||
* Key selection 101
|
||||
*
|
||||
* There are four types of keys:
|
||||
* There are five types of keys:
|
||||
* - GTK (group keys)
|
||||
* - IGTK (group keys for management frames)
|
||||
* - BIGTK (group keys for Beacon frames)
|
||||
* - PTK (pairwise keys)
|
||||
* - STK (station-to-station pairwise keys)
|
||||
*
|
||||
* When selecting a key, we have to distinguish between multicast
|
||||
* (including broadcast) and unicast frames, the latter can only
|
||||
* use PTKs and STKs while the former always use GTKs and IGTKs.
|
||||
* Unless, of course, actual WEP keys ("pre-RSNA") are used, then
|
||||
* unicast frames can also use key indices like GTKs. Hence, if we
|
||||
* use PTKs and STKs while the former always use GTKs, IGTKs, and
|
||||
* BIGTKs. Unless, of course, actual WEP keys ("pre-RSNA") are used,
|
||||
* then unicast frames can also use key indices like GTKs. Hence, if we
|
||||
* don't have a PTK/STK we check the key index for a WEP key.
|
||||
*
|
||||
* Note that in a regular BSS, multicast frames are sent by the
|
||||
|
@ -1939,6 +1976,20 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
|||
/* Skip decryption if the frame is not protected. */
|
||||
if (!ieee80211_has_protected(fc))
|
||||
return RX_CONTINUE;
|
||||
} else if (mmie_keyidx >= 0 && ieee80211_is_beacon(fc)) {
|
||||
/* Broadcast/multicast robust management frame / BIP */
|
||||
if ((status->flag & RX_FLAG_DECRYPTED) &&
|
||||
(status->flag & RX_FLAG_IV_STRIPPED))
|
||||
return RX_CONTINUE;
|
||||
|
||||
if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
|
||||
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS)
|
||||
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
|
||||
|
||||
rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
|
||||
if (!rx->key)
|
||||
return RX_CONTINUE; /* Beacon protection not in use */
|
||||
} else if (mmie_keyidx >= 0) {
|
||||
/* Broadcast/multicast robust management frame / BIP */
|
||||
if ((status->flag & RX_FLAG_DECRYPTED) &&
|
||||
|
@ -1968,11 +2019,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
|||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
int i;
|
||||
|
||||
if (ieee80211_is_mgmt(fc) &&
|
||||
is_multicast_ether_addr(hdr->addr1) &&
|
||||
(key = rcu_dereference(rx->sdata->default_mgmt_key)))
|
||||
rx->key = key;
|
||||
else {
|
||||
if (ieee80211_is_beacon(fc)) {
|
||||
key = ieee80211_rx_get_bigtk(rx, -1);
|
||||
} else if (ieee80211_is_mgmt(fc) &&
|
||||
is_multicast_ether_addr(hdr->addr1)) {
|
||||
key = rcu_dereference(rx->sdata->default_mgmt_key);
|
||||
} else {
|
||||
if (rx->sta) {
|
||||
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
|
||||
key = rcu_dereference(rx->sta->gtk[i]);
|
||||
|
@ -1987,9 +2039,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (key)
|
||||
rx->key = key;
|
||||
}
|
||||
if (key)
|
||||
rx->key = key;
|
||||
return RX_CONTINUE;
|
||||
} else {
|
||||
/*
|
||||
|
@ -2358,6 +2410,9 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
|
|||
rx->skb->len);
|
||||
return -EACCES;
|
||||
}
|
||||
if (unlikely(ieee80211_is_beacon(fc) && rx->key &&
|
||||
ieee80211_get_mmie_keyidx(rx->skb) < 0))
|
||||
return -EACCES;
|
||||
/*
|
||||
* When using MFP, Action frames are not allowed prior to
|
||||
* having configured keys.
|
||||
|
|
|
@ -201,8 +201,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
|||
mgmt->bssid, cbss->bssid);
|
||||
|
||||
/* In case the signal is invalid update the status */
|
||||
signal_valid = abs(channel->center_freq - cbss->channel->center_freq)
|
||||
<= local->hw.wiphy->max_adj_channel_rssi_comp;
|
||||
signal_valid = channel == cbss->channel;
|
||||
if (!signal_valid)
|
||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
|
||||
|
|
|
@ -533,7 +533,9 @@ struct sta_info {
|
|||
u8 addr[ETH_ALEN];
|
||||
struct ieee80211_local *local;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
|
||||
struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS +
|
||||
NUM_DEFAULT_MGMT_KEYS +
|
||||
NUM_DEFAULT_BEACON_KEYS];
|
||||
struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS];
|
||||
u8 ptk_idx;
|
||||
struct rate_control_ref *rate_ctrl;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
*
|
||||
* Transmit and frame generation functions.
|
||||
*/
|
||||
|
@ -3682,7 +3682,8 @@ begin:
|
|||
encap_out:
|
||||
IEEE80211_SKB_CB(skb)->control.vif = vif;
|
||||
|
||||
if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
||||
if (vif &&
|
||||
wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
||||
u32 airtime;
|
||||
|
||||
airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
|
||||
|
@ -4663,6 +4664,28 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_csa_is_complete);
|
||||
|
||||
static int ieee80211_beacon_protect(struct sk_buff *skb,
|
||||
struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
ieee80211_tx_result res;
|
||||
struct ieee80211_tx_data tx;
|
||||
|
||||
memset(&tx, 0, sizeof(tx));
|
||||
tx.key = rcu_dereference(sdata->default_beacon_key);
|
||||
if (!tx.key)
|
||||
return 0;
|
||||
tx.local = local;
|
||||
tx.sdata = sdata;
|
||||
__skb_queue_head_init(&tx.skbs);
|
||||
__skb_queue_tail(&tx.skbs, skb);
|
||||
res = ieee80211_tx_h_encrypt(&tx);
|
||||
if (WARN_ON_ONCE(res != TX_CONTINUE))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
__ieee80211_beacon_get(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
|
@ -4730,6 +4753,9 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
|
|||
if (beacon->tail)
|
||||
skb_put_data(skb, beacon->tail,
|
||||
beacon->tail_len);
|
||||
|
||||
if (ieee80211_beacon_protect(skb, local, sdata) < 0)
|
||||
goto out;
|
||||
} else
|
||||
goto out;
|
||||
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
|
@ -5282,8 +5308,7 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const u8 *src, __be16 proto,
|
||||
bool unencrypted)
|
||||
const u8 *dest, __be16 proto, bool unencrypted)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
@ -5314,7 +5339,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
|||
|
||||
ehdr = skb_push(skb, sizeof(struct ethhdr));
|
||||
memcpy(ehdr->h_dest, dest, ETH_ALEN);
|
||||
memcpy(ehdr->h_source, src, ETH_ALEN);
|
||||
memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
|
||||
ehdr->h_proto = proto;
|
||||
|
||||
skb->dev = dev;
|
||||
|
|
|
@ -328,6 +328,22 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
|
|||
[NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
|
||||
[NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
|
||||
[NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
|
||||
[NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
|
||||
[NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
|
||||
[NL80211_TID_CONFIG_ATTR_NOACK] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
[NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
|
||||
[NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
|
||||
[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
};
|
||||
|
||||
const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
|
@ -368,7 +384,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
|
||||
[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
|
||||
.len = WLAN_MAX_KEY_LEN },
|
||||
[NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 5),
|
||||
[NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
|
||||
[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
|
||||
|
@ -634,8 +650,8 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
|
||||
[NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
|
||||
[NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
|
||||
[NL80211_ATTR_SRC_MAC] = NLA_POLICY_ETH_ADDR,
|
||||
[NL80211_ATTR_DST_MAC] = NLA_POLICY_ETH_ADDR,
|
||||
[NL80211_ATTR_TID_CONFIG] =
|
||||
NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -1039,7 +1055,7 @@ struct key_parse {
|
|||
struct key_params p;
|
||||
int idx;
|
||||
int type;
|
||||
bool def, defmgmt;
|
||||
bool def, defmgmt, defbeacon;
|
||||
bool def_uni, def_multi;
|
||||
};
|
||||
|
||||
|
@ -1055,12 +1071,13 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
|
|||
|
||||
k->def = !!tb[NL80211_KEY_DEFAULT];
|
||||
k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
|
||||
k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
|
||||
|
||||
if (k->def) {
|
||||
k->def_uni = true;
|
||||
k->def_multi = true;
|
||||
}
|
||||
if (k->defmgmt)
|
||||
if (k->defmgmt || k->defbeacon)
|
||||
k->def_multi = true;
|
||||
|
||||
if (tb[NL80211_KEY_IDX])
|
||||
|
@ -1167,14 +1184,17 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (k->def && k->defmgmt) {
|
||||
GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid");
|
||||
if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
|
||||
(k->defbeacon ? 1 : 0) > 1) {
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"key with multiple default flags is invalid");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k->defmgmt) {
|
||||
if (k->defmgmt || k->defbeacon) {
|
||||
if (k->def_uni || !k->def_multi) {
|
||||
GENL_SET_ERR_MSG(info, "defmgmt key must be mcast");
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"defmgmt/defbeacon key must be mcast");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1186,14 +1206,20 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
|
|||
"defmgmt key idx not 4 or 5");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (k->defbeacon) {
|
||||
if (k->idx < 6 || k->idx > 7) {
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"defbeacon key idx not 6 or 7");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (k->def) {
|
||||
if (k->idx < 0 || k->idx > 3) {
|
||||
GENL_SET_ERR_MSG(info, "def key idx not 0-3");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (k->idx < 0 || k->idx > 5) {
|
||||
GENL_SET_ERR_MSG(info, "key idx not 0-5");
|
||||
if (k->idx < 0 || k->idx > 7) {
|
||||
GENL_SET_ERR_MSG(info, "key idx not 0-7");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1939,6 +1965,48 @@ nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
|
||||
struct sk_buff *msg)
|
||||
{
|
||||
struct nlattr *supp;
|
||||
|
||||
if (!rdev->wiphy.tid_config_support.vif &&
|
||||
!rdev->wiphy.tid_config_support.peer)
|
||||
return 0;
|
||||
|
||||
supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
|
||||
if (!supp)
|
||||
return -ENOSPC;
|
||||
|
||||
if (rdev->wiphy.tid_config_support.vif &&
|
||||
nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
|
||||
rdev->wiphy.tid_config_support.vif,
|
||||
NL80211_TID_CONFIG_ATTR_PAD))
|
||||
goto fail;
|
||||
|
||||
if (rdev->wiphy.tid_config_support.peer &&
|
||||
nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
|
||||
rdev->wiphy.tid_config_support.peer,
|
||||
NL80211_TID_CONFIG_ATTR_PAD))
|
||||
goto fail;
|
||||
|
||||
/* for now we just use the same value ... makes more sense */
|
||||
if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
|
||||
rdev->wiphy.tid_config_support.max_retry))
|
||||
goto fail;
|
||||
if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
|
||||
rdev->wiphy.tid_config_support.max_retry))
|
||||
goto fail;
|
||||
|
||||
nla_nest_end(msg, supp);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
nla_nest_cancel(msg, supp);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
struct nl80211_dump_wiphy_state {
|
||||
s64 filter_wiphy;
|
||||
long start;
|
||||
|
@ -2500,6 +2568,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
|
|||
if (nl80211_put_iftype_akm_suites(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nl80211_put_tid_config_support(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
break;
|
||||
|
@ -3819,8 +3890,14 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
|
|||
void *hdr;
|
||||
struct sk_buff *msg;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_KEY_IDX])
|
||||
if (info->attrs[NL80211_ATTR_KEY_IDX]) {
|
||||
key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
|
||||
if (key_idx > 5 &&
|
||||
!wiphy_ext_feature_isset(
|
||||
&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
@ -3896,7 +3973,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
|
|||
/* Only support setting default key and
|
||||
* Extended Key ID action NL80211_KEY_SET_TX.
|
||||
*/
|
||||
if (!key.def && !key.defmgmt &&
|
||||
if (!key.def && !key.defmgmt && !key.defbeacon &&
|
||||
!(key.p.mode == NL80211_KEY_SET_TX))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -3943,6 +4020,24 @@ 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.defbeacon) {
|
||||
if (key.def_uni || !key.def_multi) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rdev->ops->set_default_beacon_key) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = nl80211_key_allowed(dev->ieee80211_ptr);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = rdev_set_default_beacon_key(rdev, dev, key.idx);
|
||||
if (err)
|
||||
goto out;
|
||||
} else if (key.p.mode == NL80211_KEY_SET_TX &&
|
||||
wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_EXT_KEY_ID)) {
|
||||
|
@ -3980,8 +4075,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (!key.p.key)
|
||||
if (!key.p.key) {
|
||||
GENL_SET_ERR_MSG(info, "no key");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
@ -3995,8 +4092,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
/* for now */
|
||||
if (key.type != NL80211_KEYTYPE_PAIRWISE &&
|
||||
key.type != NL80211_KEYTYPE_GROUP)
|
||||
key.type != NL80211_KEYTYPE_GROUP) {
|
||||
GENL_SET_ERR_MSG(info, "key type not pairwise or group");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (key.type == NL80211_KEYTYPE_GROUP &&
|
||||
info->attrs[NL80211_ATTR_VLAN_ID])
|
||||
|
@ -4007,15 +4106,22 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
|
||||
key.type == NL80211_KEYTYPE_PAIRWISE,
|
||||
mac_addr))
|
||||
mac_addr)) {
|
||||
GENL_SET_ERR_MSG(info, "key setting validation failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wdev_lock(dev->ieee80211_ptr);
|
||||
err = nl80211_key_allowed(dev->ieee80211_ptr);
|
||||
if (!err)
|
||||
if (err)
|
||||
GENL_SET_ERR_MSG(info, "key not allowed");
|
||||
if (!err) {
|
||||
err = rdev_add_key(rdev, dev, key.idx,
|
||||
key.type == NL80211_KEYTYPE_PAIRWISE,
|
||||
mac_addr, &key.p);
|
||||
if (err)
|
||||
GENL_SET_ERR_MSG(info, "key addition failed");
|
||||
}
|
||||
wdev_unlock(dev->ieee80211_ptr);
|
||||
|
||||
return err;
|
||||
|
@ -13698,7 +13804,6 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
|||
const u8 *buf;
|
||||
size_t len;
|
||||
u8 *dest;
|
||||
u8 src[ETH_ALEN];
|
||||
u16 proto;
|
||||
bool noencrypt;
|
||||
int err;
|
||||
|
@ -13736,13 +13841,6 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* copy src address under wdev_lock, as we may copy wdev_address */
|
||||
if (info->attrs[NL80211_ATTR_SRC_MAC])
|
||||
ether_addr_copy(src,
|
||||
nla_data(info->attrs[NL80211_ATTR_SRC_MAC]));
|
||||
else
|
||||
ether_addr_copy(src, wdev_address(wdev));
|
||||
|
||||
wdev_unlock(wdev);
|
||||
|
||||
buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
||||
|
@ -13753,7 +13851,7 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
|||
nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
|
||||
|
||||
return rdev_tx_control_port(rdev, dev, buf, len,
|
||||
dest, src, cpu_to_be16(proto), noencrypt);
|
||||
dest, cpu_to_be16(proto), noencrypt);
|
||||
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
|
@ -13899,6 +13997,141 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
|
|||
return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
|
||||
}
|
||||
|
||||
static int parse_tid_conf(struct cfg80211_registered_device *rdev,
|
||||
struct nlattr *attrs[], struct net_device *dev,
|
||||
struct cfg80211_tid_cfg *tid_conf,
|
||||
struct genl_info *info, const u8 *peer)
|
||||
{
|
||||
struct netlink_ext_ack *extack = info->extack;
|
||||
u64 mask;
|
||||
int err;
|
||||
|
||||
if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
|
||||
return -EINVAL;
|
||||
|
||||
tid_conf->config_override =
|
||||
nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
|
||||
tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
|
||||
|
||||
if (tid_conf->config_override) {
|
||||
if (rdev->ops->reset_tid_config) {
|
||||
err = rdev_reset_tid_config(rdev, dev, peer,
|
||||
tid_conf->tids);
|
||||
/* If peer is there no other configuration will be
|
||||
* allowed
|
||||
*/
|
||||
if (err || peer)
|
||||
return err;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
|
||||
tid_conf->noack =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
|
||||
tid_conf->retry_short =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
|
||||
|
||||
if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
|
||||
tid_conf->retry_long =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
|
||||
|
||||
if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
|
||||
tid_conf->ampdu =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
|
||||
tid_conf->rtscts =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
|
||||
}
|
||||
|
||||
if (peer)
|
||||
mask = rdev->wiphy.tid_config_support.peer;
|
||||
else
|
||||
mask = rdev->wiphy.tid_config_support.vif;
|
||||
|
||||
if (tid_conf->mask & ~mask) {
|
||||
NL_SET_ERR_MSG(extack, "unsupported TID configuration");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_set_tid_config(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct cfg80211_tid_config *tid_config;
|
||||
struct nlattr *tid;
|
||||
int conf_idx = 0, rem_conf;
|
||||
int ret = -EINVAL;
|
||||
u32 num_conf = 0;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_TID_CONFIG])
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdev->ops->set_tid_config)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
|
||||
rem_conf)
|
||||
num_conf++;
|
||||
|
||||
tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
|
||||
GFP_KERNEL);
|
||||
if (!tid_config)
|
||||
return -ENOMEM;
|
||||
|
||||
tid_config->n_tid_conf = num_conf;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
||||
nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
|
||||
rem_conf) {
|
||||
ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
|
||||
tid, NULL, NULL);
|
||||
|
||||
if (ret)
|
||||
goto bad_tid_conf;
|
||||
|
||||
ret = parse_tid_conf(rdev, attrs, dev,
|
||||
&tid_config->tid_conf[conf_idx],
|
||||
info, tid_config->peer);
|
||||
if (ret)
|
||||
goto bad_tid_conf;
|
||||
|
||||
conf_idx++;
|
||||
}
|
||||
|
||||
ret = rdev_set_tid_config(rdev, dev, tid_config);
|
||||
|
||||
bad_tid_conf:
|
||||
kfree(tid_config);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
|
@ -14853,6 +15086,13 @@ static const struct genl_ops nl80211_ops[] = {
|
|||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_SET_TID_CONFIG,
|
||||
.doit = nl80211_set_tid_config,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __ro_after_init = {
|
||||
|
@ -16010,8 +16250,7 @@ static int __nl80211_rx_control_port(struct net_device *dev,
|
|||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ethhdr *ehdr = eth_hdr(skb);
|
||||
const u8 *daddr = ehdr->h_dest;
|
||||
const u8 *saddr = ehdr->h_source;
|
||||
const u8 *addr = ehdr->h_source;
|
||||
u16 proto = be16_to_cpu(skb->protocol);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
@ -16036,8 +16275,7 @@ static int __nl80211_rx_control_port(struct net_device *dev,
|
|||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
|
||||
nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
|
||||
NL80211_ATTR_PAD) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, saddr) ||
|
||||
nla_put(msg, NL80211_ATTR_DST_MAC, ETH_ALEN, daddr) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
|
||||
nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
|
||||
(unencrypted && nla_put_flag(msg,
|
||||
NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
|
||||
|
|
|
@ -136,6 +136,19 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u8 key_index)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index);
|
||||
ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev,
|
||||
key_index);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_start_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ap_settings *settings)
|
||||
|
@ -734,14 +747,14 @@ static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
|
|||
static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
const void *buf, size_t len,
|
||||
const u8 *dest, const u8 *src,
|
||||
__be16 proto, const bool noencrypt)
|
||||
const u8 *dest, __be16 proto,
|
||||
const bool noencrypt)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, src, proto, noencrypt);
|
||||
dest, proto, noencrypt);
|
||||
ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, src, proto, noencrypt);
|
||||
dest, proto, noencrypt);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1313,4 +1326,28 @@ rdev_probe_mesh_link(struct cfg80211_registered_device *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_set_tid_config(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_tid_config *tid_conf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace_rdev_set_tid_config(&rdev->wiphy, dev, tid_conf);
|
||||
ret = rdev->ops->set_tid_config(&rdev->wiphy, dev, tid_conf);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_reset_tid_config(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, const u8 *peer,
|
||||
u8 tids)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace_rdev_reset_tid_config(&rdev->wiphy, dev, peer, tids);
|
||||
ret = rdev->ops->reset_tid_config(&rdev->wiphy, dev, peer, tids);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
|
|
|
@ -556,9 +556,8 @@ cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
|
|||
{
|
||||
struct cfg80211_sched_scan_request *pos;
|
||||
|
||||
WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held());
|
||||
|
||||
list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list) {
|
||||
list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list,
|
||||
lockdep_rtnl_is_held()) {
|
||||
if (pos->reqid == reqid)
|
||||
return pos;
|
||||
}
|
||||
|
@ -1434,8 +1433,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
|
|||
}
|
||||
rcu_assign_pointer(tmp.pub.ies, ies);
|
||||
|
||||
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
signal_valid = data->chan == channel;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid, ts);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
@ -1852,8 +1850,7 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
|
|||
memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
|
||||
ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
|
||||
|
||||
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
signal_valid = data->chan == channel;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
|
||||
jiffies);
|
||||
if (!res)
|
||||
|
|
|
@ -1111,9 +1111,16 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
|||
* Delete all the keys ... pairwise keys can't really
|
||||
* exist any more anyway, but default keys might.
|
||||
*/
|
||||
if (rdev->ops->del_key)
|
||||
for (i = 0; i < 6; i++)
|
||||
if (rdev->ops->del_key) {
|
||||
int max_key_idx = 5;
|
||||
|
||||
if (wiphy_ext_feature_isset(
|
||||
wdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
max_key_idx = 7;
|
||||
for (i = 0; i <= max_key_idx; i++)
|
||||
rdev_del_key(rdev, dev, i, false, NULL);
|
||||
}
|
||||
|
||||
rdev_set_qos_map(rdev, dev, NULL);
|
||||
|
||||
|
|
|
@ -510,6 +510,23 @@ TRACE_EVENT(rdev_set_default_mgmt_key,
|
|||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_default_beacon_key,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index),
|
||||
TP_ARGS(wiphy, netdev, key_index),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
__field(u8, key_index)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
__entry->key_index = key_index;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_start_ap,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_ap_settings *settings),
|
||||
|
@ -1928,31 +1945,27 @@ TRACE_EVENT(rdev_mgmt_tx,
|
|||
|
||||
TRACE_EVENT(rdev_tx_control_port,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const u8 *src, __be16 proto,
|
||||
const u8 *buf, size_t len, const u8 *dest, __be16 proto,
|
||||
bool unencrypted),
|
||||
TP_ARGS(wiphy, netdev, buf, len, dest, src, proto, unencrypted),
|
||||
TP_ARGS(wiphy, netdev, buf, len, dest, proto, unencrypted),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(dest)
|
||||
MAC_ENTRY(src)
|
||||
__field(u16, proto)
|
||||
__field(__be16, proto)
|
||||
__field(bool, unencrypted)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(dest, dest);
|
||||
MAC_ASSIGN(src, src);
|
||||
__entry->proto = be16_to_cpu(proto);
|
||||
__entry->proto = proto;
|
||||
__entry->unencrypted = unencrypted;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", dest: " MAC_PR_FMT
|
||||
", src: " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
MAC_PR_ARG(dest), MAC_PR_ARG(src),
|
||||
__entry->proto,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ","
|
||||
" proto: 0x%x, unencrypted: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dest),
|
||||
be16_to_cpu(__entry->proto),
|
||||
BOOL_TO_STR(__entry->unencrypted))
|
||||
);
|
||||
|
||||
|
@ -2844,7 +2857,6 @@ TRACE_EVENT(cfg80211_rx_control_port,
|
|||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__field(int, len)
|
||||
MAC_ENTRY(to)
|
||||
MAC_ENTRY(from)
|
||||
__field(u16, proto)
|
||||
__field(bool, unencrypted)
|
||||
|
@ -2852,14 +2864,12 @@ TRACE_EVENT(cfg80211_rx_control_port,
|
|||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
__entry->len = skb->len;
|
||||
MAC_ASSIGN(to, eth_hdr(skb)->h_dest);
|
||||
MAC_ASSIGN(from, eth_hdr(skb)->h_source);
|
||||
__entry->proto = be16_to_cpu(skb->protocol);
|
||||
__entry->unencrypted = unencrypted;
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT ", len=%d, dest: " MAC_PR_FMT
|
||||
", src: " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
NETDEV_PR_ARG, __entry->len, MAC_PR_ARG(to), MAC_PR_ARG(from),
|
||||
TP_printk(NETDEV_PR_FMT ", len=%d, " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
NETDEV_PR_ARG, __entry->len, MAC_PR_ARG(from),
|
||||
__entry->proto, BOOL_TO_STR(__entry->unencrypted))
|
||||
);
|
||||
|
||||
|
@ -3470,6 +3480,43 @@ TRACE_EVENT(rdev_probe_mesh_link,
|
|||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dest))
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_tid_config,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_tid_config *tid_conf),
|
||||
TP_ARGS(wiphy, netdev, tid_conf),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(peer)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(peer, tid_conf->peer);
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_reset_tid_config,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
const u8 *peer, u8 tids),
|
||||
TP_ARGS(wiphy, netdev, peer, tids),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(peer)
|
||||
__field(u8, tids)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(peer, peer);
|
||||
__entry->tids = tids;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids)
|
||||
);
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
@ -231,7 +231,12 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
|||
struct key_params *params, int key_idx,
|
||||
bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
if (key_idx < 0 || key_idx > 5)
|
||||
int max_key_idx = 5;
|
||||
|
||||
if (wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
max_key_idx = 7;
|
||||
if (key_idx < 0 || key_idx > max_key_idx)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
|
||||
|
|
Загрузка…
Ссылка в новой задаче