Skip to content

Commit

Permalink
Merge tag 'mac80211-for-net-2020-10-30' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/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>
  • Loading branch information
Jakub Kicinski committed Nov 2, 2020
2 parents 859191b + c2f4681 commit 04a55c9
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 55 deletions.
9 changes: 5 additions & 4 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
18 changes: 18 additions & 0 deletions net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
9 changes: 8 additions & 1 deletion net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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);
Expand Down
44 changes: 28 additions & 16 deletions net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) &&
Expand Down
57 changes: 31 additions & 26 deletions net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -1295,42 +1318,24 @@ 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:
/*
* NB: cannot take rdev->mtx here because this may be
* 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);
Expand Down
5 changes: 3 additions & 2 deletions net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion net/wireless/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3616,7 +3616,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
power_rule = &reg_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
Expand Down

0 comments on commit 04a55c9

Please sign in to comment.