Commit 1ea06107 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-for-davem-2019-02-12' of...

Merge tag 'mac80211-for-davem-2019-02-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Just a few fixes:
 * aggregation session teardown with internal TXQs was
   continuing to send some frames marked as aggregation,
   fix from Ilan
 * IBSS join was missed during firmware restart, should
   such a thing happen
 * speculative execution based on the return value of
   cfg80211_classify8021d() - which is controlled by the
   sender of the packet - could be problematic in some
   code using it, prevent it
 * a few peer measurement fixes
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 91986ee1 6157ca0d
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation * Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH * Copyright(c) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018 - 2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -366,6 +366,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, ...@@ -366,6 +366,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
ieee80211_agg_stop_txq(sta, tid);
spin_unlock_bh(&sta->lock); spin_unlock_bh(&sta->lock);
ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n", ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018-2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -2146,6 +2146,10 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -2146,6 +2146,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_MONITOR:
break; break;
case NL80211_IFTYPE_ADHOC:
if (sdata->vif.bss_conf.ibss_joined)
WARN_ON(drv_join_ibss(local, sdata));
/* fall through */
default: default:
ieee80211_reconfig_stations(sdata); ieee80211_reconfig_stations(sdata);
/* fall through */ /* fall through */
......
...@@ -1068,6 +1068,8 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync) ...@@ -1068,6 +1068,8 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync)
ASSERT_RTNL(); ASSERT_RTNL();
flush_work(&wdev->pmsr_free_wk);
nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE); nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);
list_del_rcu(&wdev->list); list_del_rcu(&wdev->list);
......
...@@ -250,7 +250,7 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = { ...@@ -250,7 +250,7 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] = [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
NLA_POLICY_MAX(NLA_U8, 15), NLA_POLICY_MAX(NLA_U8, 15),
[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] = [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
NLA_POLICY_MAX(NLA_U8, 15), NLA_POLICY_MAX(NLA_U8, 31),
[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 }, [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG }, [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG }, [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
......
...@@ -256,8 +256,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info) ...@@ -256,8 +256,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
goto out_err; goto out_err;
} else { } else {
memcpy(req->mac_addr, nla_data(info->attrs[NL80211_ATTR_MAC]), memcpy(req->mac_addr, wdev_address(wdev), ETH_ALEN);
ETH_ALEN);
memset(req->mac_addr_mask, 0xff, ETH_ALEN); memset(req->mac_addr_mask, 0xff, ETH_ALEN);
} }
...@@ -272,6 +271,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info) ...@@ -272,6 +271,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
req->n_peers = count; req->n_peers = count;
req->cookie = cfg80211_assign_cookie(rdev); req->cookie = cfg80211_assign_cookie(rdev);
req->nl_portid = info->snd_portid;
err = rdev_start_pmsr(rdev, wdev, req); err = rdev_start_pmsr(rdev, wdev, req);
if (err) if (err)
...@@ -530,14 +530,14 @@ void cfg80211_pmsr_report(struct wireless_dev *wdev, ...@@ -530,14 +530,14 @@ void cfg80211_pmsr_report(struct wireless_dev *wdev,
} }
EXPORT_SYMBOL_GPL(cfg80211_pmsr_report); EXPORT_SYMBOL_GPL(cfg80211_pmsr_report);
void cfg80211_pmsr_free_wk(struct work_struct *work) static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
{ {
struct wireless_dev *wdev = container_of(work, struct wireless_dev,
pmsr_free_wk);
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct cfg80211_pmsr_request *req, *tmp; struct cfg80211_pmsr_request *req, *tmp;
LIST_HEAD(free_list); LIST_HEAD(free_list);
lockdep_assert_held(&wdev->mtx);
spin_lock_bh(&wdev->pmsr_lock); spin_lock_bh(&wdev->pmsr_lock);
list_for_each_entry_safe(req, tmp, &wdev->pmsr_list, list) { list_for_each_entry_safe(req, tmp, &wdev->pmsr_list, list) {
if (req->nl_portid) if (req->nl_portid)
...@@ -547,14 +547,22 @@ void cfg80211_pmsr_free_wk(struct work_struct *work) ...@@ -547,14 +547,22 @@ void cfg80211_pmsr_free_wk(struct work_struct *work)
spin_unlock_bh(&wdev->pmsr_lock); spin_unlock_bh(&wdev->pmsr_lock);
list_for_each_entry_safe(req, tmp, &free_list, list) { list_for_each_entry_safe(req, tmp, &free_list, list) {
wdev_lock(wdev);
rdev_abort_pmsr(rdev, wdev, req); rdev_abort_pmsr(rdev, wdev, req);
wdev_unlock(wdev);
kfree(req); kfree(req);
} }
} }
void cfg80211_pmsr_free_wk(struct work_struct *work)
{
struct wireless_dev *wdev = container_of(work, struct wireless_dev,
pmsr_free_wk);
wdev_lock(wdev);
cfg80211_pmsr_process_abort(wdev);
wdev_unlock(wdev);
}
void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev) void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
{ {
struct cfg80211_pmsr_request *req; struct cfg80211_pmsr_request *req;
...@@ -568,8 +576,8 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev) ...@@ -568,8 +576,8 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
spin_unlock_bh(&wdev->pmsr_lock); spin_unlock_bh(&wdev->pmsr_lock);
if (found) if (found)
schedule_work(&wdev->pmsr_free_wk); cfg80211_pmsr_process_abort(wdev);
flush_work(&wdev->pmsr_free_wk);
WARN_ON(!list_empty(&wdev->pmsr_list)); WARN_ON(!list_empty(&wdev->pmsr_list));
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2017 Intel Deutschland GmbH * Copyright 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018-2019 Intel Corporation
*/ */
#include <linux/export.h> #include <linux/export.h>
#include <linux/bitops.h> #include <linux/bitops.h>
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/mpls.h> #include <linux/mpls.h>
#include <linux/gcd.h> #include <linux/gcd.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/nospec.h>
#include "core.h" #include "core.h"
#include "rdev-ops.h" #include "rdev-ops.h"
...@@ -715,20 +716,25 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb, ...@@ -715,20 +716,25 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
{ {
unsigned int dscp; unsigned int dscp;
unsigned char vlan_priority; unsigned char vlan_priority;
unsigned int ret;
/* skb->priority values from 256->263 are magic values to /* skb->priority values from 256->263 are magic values to
* directly indicate a specific 802.1d priority. This is used * directly indicate a specific 802.1d priority. This is used
* to allow 802.1d priority to be passed directly in from VLAN * to allow 802.1d priority to be passed directly in from VLAN
* tags, etc. * tags, etc.
*/ */
if (skb->priority >= 256 && skb->priority <= 263) if (skb->priority >= 256 && skb->priority <= 263) {
return skb->priority - 256; ret = skb->priority - 256;
goto out;
}
if (skb_vlan_tag_present(skb)) { if (skb_vlan_tag_present(skb)) {
vlan_priority = (skb_vlan_tag_get(skb) & VLAN_PRIO_MASK) vlan_priority = (skb_vlan_tag_get(skb) & VLAN_PRIO_MASK)
>> VLAN_PRIO_SHIFT; >> VLAN_PRIO_SHIFT;
if (vlan_priority > 0) if (vlan_priority > 0) {
return vlan_priority; ret = vlan_priority;
goto out;
}
} }
switch (skb->protocol) { switch (skb->protocol) {
...@@ -747,8 +753,9 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb, ...@@ -747,8 +753,9 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
if (!mpls) if (!mpls)
return 0; return 0;
return (ntohl(mpls->entry) & MPLS_LS_TC_MASK) ret = (ntohl(mpls->entry) & MPLS_LS_TC_MASK)
>> MPLS_LS_TC_SHIFT; >> MPLS_LS_TC_SHIFT;
goto out;
} }
case htons(ETH_P_80221): case htons(ETH_P_80221):
/* 802.21 is always network control traffic */ /* 802.21 is always network control traffic */
...@@ -761,18 +768,24 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb, ...@@ -761,18 +768,24 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
unsigned int i, tmp_dscp = dscp >> 2; unsigned int i, tmp_dscp = dscp >> 2;
for (i = 0; i < qos_map->num_des; i++) { for (i = 0; i < qos_map->num_des; i++) {
if (tmp_dscp == qos_map->dscp_exception[i].dscp) if (tmp_dscp == qos_map->dscp_exception[i].dscp) {
return qos_map->dscp_exception[i].up; ret = qos_map->dscp_exception[i].up;
goto out;
}
} }
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (tmp_dscp >= qos_map->up[i].low && if (tmp_dscp >= qos_map->up[i].low &&
tmp_dscp <= qos_map->up[i].high) tmp_dscp <= qos_map->up[i].high) {
return i; ret = i;
goto out;
}
} }
} }
return dscp >> 5; ret = dscp >> 5;
out:
return array_index_nospec(ret, IEEE80211_NUM_TIDS);
} }
EXPORT_SYMBOL(cfg80211_classify8021d); EXPORT_SYMBOL(cfg80211_classify8021d);
......
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