Commit 04a55c94 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'mac80211-for-net-2020-10-30' of...

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: default avatarJakub Kicinski <kuba@kernel.org>
parents 859191b2 c2f46814
......@@ -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 = &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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment