mirror of https://gitee.com/openkylin/linux.git
A couple of fixes, for
* HE on 2.4 GHz * a few issues syzbot found, but we have many more reports :-( * a regression in nl80211-transported EAPOL frames which had affected a number of users, from Mathy * kernel-doc markings in mac80211, from Mauro * a format argument in reg.c, from Ye Bin -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl+b4B0ACgkQB8qZga/f l8SdOg/+PcKqoNXh+VgP2ZvCcN3D/3ow5mf9OgNijPoM35a4sJZdGpRWp1oUXK8O 1NbyE/mL3TiNS5HIb+jF03+pHOl+ysh0AE3QsQeZwn+bHkU61T9J477NQr4Y9hQ0 eJZxDjgSUsJhx1xnGPH0QFUi7zaFQAfy1Q5AVCPP5ywEOovTuOY9Qw/7D2EZoh5L k2H1kjLIle2VCckqrL5pno3dz1lAGRZ5RGGiP8/ATfBH6pYON9yFSflc9x6azTS2 vWyfZxzbrFWvT2YFMwNUnNl4oNjLIvGYmYzULp9MweyFA6lfZpIOAcGtVoM98nD7 wu6KWeozo4c+3D25kqxRlpE6fILJ+uiCKcHV+7GyLsDkp9s2onE5f/UHmcP+pGkh QE/ubTbe2brWSpPwHyAXEg1FQ3WPmJj90Tr3OA2j+rIfh/+eUH/inoxvddqyOamR mBr8M1VRY8+PRAru9UKU+EG4CueX5GALxbOH8rJFtlDsJz33CxGm1sxpAc9pR4CX XYuaPYsunok7/tXRxXulaCE0B6DOqyhX8L7drVJ0nEpAv7J3WfkZxlFs8+3VPBG7 BMiwNqNMKHM613a16vvl8ZOsguzRPIxhPLWVbcUb5c6NQq+4FOn5pZYtZU8jZ19e w3iDPbfaCCARnf5U5JKqTt45q+71rbU9pSncMjy7r5/r1hPGwiQ= =2AGz -----END PGP SIGNATURE----- Merge tag 'mac80211-for-net-2020-10-30' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 Johannes Berg says: ==================== A couple of fixes, for * HE on 2.4 GHz * a few issues syzbot found, but we have many more reports :-( * a regression in nl80211-transported EAPOL frames which had affected a number of users, from Mathy * kernel-doc markings in mac80211, from Mauro * a format argument in reg.c, from Ye Bin ==================== Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
04a55c944f
|
@ -1444,7 +1444,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
|
|||
enum cfg80211_station_type statype);
|
||||
|
||||
/**
|
||||
* enum station_info_rate_flags - bitrate info flags
|
||||
* enum rate_info_flags - bitrate info flags
|
||||
*
|
||||
* Used by the driver to indicate the specific rate transmission
|
||||
* type for 802.11n transmissions.
|
||||
|
@ -1517,7 +1517,7 @@ struct rate_info {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum station_info_rate_flags - bitrate info flags
|
||||
* enum bss_param_flags - bitrate info flags
|
||||
*
|
||||
* Used by the driver to indicate the specific rate transmission
|
||||
* type for 802.11n transmissions.
|
||||
|
@ -6467,7 +6467,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
|
|||
struct ieee80211_channel *channel, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
|
||||
* cfg80211_notify_new_peer_candidate - notify cfg80211 of a new mesh peer
|
||||
* candidate
|
||||
*
|
||||
* @dev: network device
|
||||
* @macaddr: the MAC address of the new candidate
|
||||
|
@ -7606,7 +7607,7 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
|
|||
void cfg80211_unregister_wdev(struct wireless_dev *wdev);
|
||||
|
||||
/**
|
||||
* struct cfg80211_ft_event - FT Information Elements
|
||||
* struct cfg80211_ft_event_params - FT Information Elements
|
||||
* @ies: FT IEs
|
||||
* @ies_len: length of the FT IE in bytes
|
||||
* @target_ap: target AP's MAC address
|
||||
|
|
|
@ -3311,7 +3311,7 @@ enum ieee80211_roc_type {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_reconfig_complete_type - reconfig type
|
||||
* enum ieee80211_reconfig_type - reconfig type
|
||||
*
|
||||
* This enum is used by the reconfig_complete() callback to indicate what
|
||||
* reconfiguration type was completed.
|
||||
|
@ -6334,7 +6334,8 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
|
|||
int band, struct ieee80211_sta **sta);
|
||||
|
||||
/**
|
||||
* Sanity-check and parse the radiotap header of injected frames
|
||||
* ieee80211_parse_tx_radiotap - Sanity-check and parse the radiotap header
|
||||
* of injected frames
|
||||
* @skb: packet injected by userspace
|
||||
* @dev: the &struct device of this 802.11 device
|
||||
*/
|
||||
|
@ -6389,7 +6390,7 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
|
|||
void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf);
|
||||
|
||||
/**
|
||||
* ieee80211_tdls_oper - request userspace to perform a TDLS operation
|
||||
* ieee80211_tdls_oper_request - request userspace to perform a TDLS operation
|
||||
* @vif: virtual interface
|
||||
* @peer: the peer's destination address
|
||||
* @oper: the requested TDLS operation
|
||||
|
|
|
@ -5464,6 +5464,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
struct cfg80211_assoc_request *req)
|
||||
{
|
||||
bool is_6ghz = req->bss->channel->band == NL80211_BAND_6GHZ;
|
||||
bool is_5ghz = req->bss->channel->band == NL80211_BAND_5GHZ;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss *bss = (void *)req->bss->priv;
|
||||
|
@ -5616,7 +5617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
if (vht_ie && vht_ie[1] >= sizeof(struct ieee80211_vht_cap))
|
||||
memcpy(&assoc_data->ap_vht_cap, vht_ie + 2,
|
||||
sizeof(struct ieee80211_vht_cap));
|
||||
else if (!is_6ghz)
|
||||
else if (is_5ghz)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -258,6 +258,24 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
|
|||
*/
|
||||
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
|
||||
{
|
||||
/*
|
||||
* If we had used sta_info_pre_move_state() then we might not
|
||||
* have gone through the state transitions down again, so do
|
||||
* it here now (and warn if it's inserted).
|
||||
*
|
||||
* This will clear state such as fast TX/RX that may have been
|
||||
* allocated during state transitions.
|
||||
*/
|
||||
while (sta->sta_state > IEEE80211_STA_NONE) {
|
||||
int ret;
|
||||
|
||||
WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
|
||||
|
||||
ret = sta_info_move_state(sta, sta->sta_state - 1);
|
||||
if (WARN_ONCE(ret, "sta_info_move_state() returned %d\n", ret))
|
||||
break;
|
||||
}
|
||||
|
||||
if (sta->rate_ctrl)
|
||||
rate_control_free_sta(sta);
|
||||
|
||||
|
|
|
@ -785,7 +785,7 @@ int sta_info_init(struct ieee80211_local *local);
|
|||
void sta_info_stop(struct ieee80211_local *local);
|
||||
|
||||
/**
|
||||
* sta_info_flush - flush matching STA entries from the STA table
|
||||
* __sta_info_flush - flush matching STA entries from the STA table
|
||||
*
|
||||
* Returns the number of removed STA entries.
|
||||
*
|
||||
|
@ -794,6 +794,13 @@ void sta_info_stop(struct ieee80211_local *local);
|
|||
*/
|
||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
|
||||
|
||||
/**
|
||||
* sta_info_flush - flush matching STA entries from the STA table
|
||||
*
|
||||
* Returns the number of removed STA entries.
|
||||
*
|
||||
* @sdata: sdata to remove all stations from
|
||||
*/
|
||||
static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
return __sta_info_flush(sdata, false);
|
||||
|
|
|
@ -1942,19 +1942,24 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* device xmit handlers */
|
||||
|
||||
enum ieee80211_encrypt {
|
||||
ENCRYPT_NO,
|
||||
ENCRYPT_MGMT,
|
||||
ENCRYPT_DATA,
|
||||
};
|
||||
|
||||
static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
int head_need, bool may_encrypt)
|
||||
int head_need,
|
||||
enum ieee80211_encrypt encrypt)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_hdr *hdr;
|
||||
bool enc_tailroom;
|
||||
int tail_need = 0;
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
enc_tailroom = may_encrypt &&
|
||||
(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||
ieee80211_is_mgmt(hdr->frame_control));
|
||||
enc_tailroom = encrypt == ENCRYPT_MGMT ||
|
||||
(encrypt == ENCRYPT_DATA &&
|
||||
sdata->crypto_tx_tailroom_needed_cnt);
|
||||
|
||||
if (enc_tailroom) {
|
||||
tail_need = IEEE80211_ENCRYPT_TAILROOM;
|
||||
|
@ -1985,23 +1990,29 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
int headroom;
|
||||
bool may_encrypt;
|
||||
enum ieee80211_encrypt encrypt;
|
||||
|
||||
may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
|
||||
if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)
|
||||
encrypt = ENCRYPT_NO;
|
||||
else if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
encrypt = ENCRYPT_MGMT;
|
||||
else
|
||||
encrypt = ENCRYPT_DATA;
|
||||
|
||||
headroom = local->tx_headroom;
|
||||
if (may_encrypt)
|
||||
if (encrypt != ENCRYPT_NO)
|
||||
headroom += sdata->encrypt_headroom;
|
||||
headroom -= skb_headroom(skb);
|
||||
headroom = max_t(int, 0, headroom);
|
||||
|
||||
if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
|
||||
if (ieee80211_skb_resize(sdata, skb, headroom, encrypt)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reload after potential resize */
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
info->control.vif = &sdata->vif;
|
||||
|
||||
|
@ -2828,7 +2839,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
head_need += sdata->encrypt_headroom;
|
||||
head_need += local->tx_headroom;
|
||||
head_need = max_t(int, 0, head_need);
|
||||
if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
|
||||
if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
skb = NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -3502,7 +3513,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
|||
if (unlikely(ieee80211_skb_resize(sdata, skb,
|
||||
max_t(int, extra_head + hw_headroom -
|
||||
skb_headroom(skb), 0),
|
||||
false))) {
|
||||
ENCRYPT_NO))) {
|
||||
kfree_skb(skb);
|
||||
return true;
|
||||
}
|
||||
|
@ -3619,13 +3630,14 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
|||
tx.skb = skb;
|
||||
tx.sdata = vif_to_sdata(info->control.vif);
|
||||
|
||||
if (txq->sta && !(info->flags & IEEE80211_TX_CTL_INJECTED)) {
|
||||
if (txq->sta) {
|
||||
tx.sta = container_of(txq->sta, struct sta_info, sta);
|
||||
/*
|
||||
* Drop unicast frames to unauthorised stations unless they are
|
||||
* EAPOL frames from the local station.
|
||||
* injected frames or EAPOL frames from the local station.
|
||||
*/
|
||||
if (unlikely(ieee80211_is_data(hdr->frame_control) &&
|
||||
if (unlikely(!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
|
||||
ieee80211_is_data(hdr->frame_control) &&
|
||||
!ieee80211_vif_is_mesh(&tx.sdata->vif) &&
|
||||
tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
|
||||
!is_multicast_ether_addr(hdr->addr1) &&
|
||||
|
|
|
@ -1250,8 +1250,7 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_stop_iface);
|
||||
|
||||
void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
void cfg80211_init_wdev(struct wireless_dev *wdev)
|
||||
{
|
||||
mutex_init(&wdev->mtx);
|
||||
INIT_LIST_HEAD(&wdev->event_list);
|
||||
|
@ -1262,6 +1261,30 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
|||
spin_lock_init(&wdev->pmsr_lock);
|
||||
INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
wdev->wext.default_key = -1;
|
||||
wdev->wext.default_mgmt_key = -1;
|
||||
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
||||
#endif
|
||||
|
||||
if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
|
||||
wdev->ps = true;
|
||||
else
|
||||
wdev->ps = false;
|
||||
/* allow mac80211 to determine the timeout */
|
||||
wdev->ps_timeout = -1;
|
||||
|
||||
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||
wdev->netdev->priv_flags |= IFF_DONT_BRIDGE;
|
||||
|
||||
INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
|
||||
}
|
||||
|
||||
void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
/*
|
||||
* We get here also when the interface changes network namespaces,
|
||||
* as it's registered into the new one, but we don't want it to
|
||||
|
@ -1295,6 +1318,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||
switch (state) {
|
||||
case NETDEV_POST_INIT:
|
||||
SET_NETDEV_DEVTYPE(dev, &wiphy_type);
|
||||
wdev->netdev = dev;
|
||||
/* can only change netns with wiphy */
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
|
||||
cfg80211_init_wdev(wdev);
|
||||
break;
|
||||
case NETDEV_REGISTER:
|
||||
/*
|
||||
|
@ -1302,35 +1330,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||
* called within code protected by it when interfaces
|
||||
* are added with nl80211.
|
||||
*/
|
||||
/* can only change netns with wiphy */
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
|
||||
if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
|
||||
"phy80211")) {
|
||||
pr_err("failed to add phy80211 symlink to netdev!\n");
|
||||
}
|
||||
wdev->netdev = dev;
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
wdev->wext.default_key = -1;
|
||||
wdev->wext.default_mgmt_key = -1;
|
||||
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
||||
#endif
|
||||
|
||||
if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
|
||||
wdev->ps = true;
|
||||
else
|
||||
wdev->ps = false;
|
||||
/* allow mac80211 to determine the timeout */
|
||||
wdev->ps_timeout = -1;
|
||||
|
||||
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||
dev->priv_flags |= IFF_DONT_BRIDGE;
|
||||
|
||||
INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
|
||||
|
||||
cfg80211_init_wdev(rdev, wdev);
|
||||
cfg80211_register_wdev(rdev, wdev);
|
||||
break;
|
||||
case NETDEV_GOING_DOWN:
|
||||
cfg80211_leave(rdev, wdev);
|
||||
|
|
|
@ -209,8 +209,9 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
|
|||
int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
|
||||
struct net *net);
|
||||
|
||||
void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
void cfg80211_init_wdev(struct wireless_dev *wdev);
|
||||
void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
|
||||
static inline void wdev_lock(struct wireless_dev *wdev)
|
||||
__acquires(wdev)
|
||||
|
|
|
@ -3885,7 +3885,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|||
* P2P Device and NAN do not have a netdev, so don't go
|
||||
* through the netdev notifier and must be added here
|
||||
*/
|
||||
cfg80211_init_wdev(rdev, wdev);
|
||||
cfg80211_init_wdev(wdev);
|
||||
cfg80211_register_wdev(rdev, wdev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -3616,7 +3616,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
|||
power_rule = ®_rule->power_rule;
|
||||
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %u KHz AUTO",
|
||||
freq_range->max_bandwidth_khz,
|
||||
reg_get_max_bandwidth(rd, reg_rule));
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue