Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
20fb9e50
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
20fb9e50
编写于
1月 30, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
上级
0f496df2
3b4797bc
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
576 addition
and
178 deletion
+576
-178
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+2
-3
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+1
-0
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+1
-2
include/linux/ieee80211.h
include/linux/ieee80211.h
+4
-1
include/net/cfg80211.h
include/net/cfg80211.h
+38
-4
include/net/mac80211.h
include/net/mac80211.h
+24
-7
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+49
-2
net/mac80211/agg-rx.c
net/mac80211/agg-rx.c
+9
-5
net/mac80211/agg-tx.c
net/mac80211/agg-tx.c
+37
-24
net/mac80211/driver-ops.h
net/mac80211/driver-ops.h
+33
-3
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+1
-2
net/mac80211/iface.c
net/mac80211/iface.c
+0
-3
net/mac80211/key.c
net/mac80211/key.c
+4
-1
net/mac80211/main.c
net/mac80211/main.c
+52
-12
net/mac80211/mesh_plink.c
net/mac80211/mesh_plink.c
+104
-64
net/mac80211/mlme.c
net/mac80211/mlme.c
+14
-28
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+0
-5
net/mac80211/trace.h
net/mac80211/trace.h
+46
-7
net/mac80211/tx.c
net/mac80211/tx.c
+4
-4
net/wireless/core.c
net/wireless/core.c
+5
-0
net/wireless/nl80211.c
net/wireless/nl80211.c
+116
-0
net/wireless/rdev-ops.h
net/wireless/rdev-ops.h
+12
-0
net/wireless/trace.h
net/wireless/trace.h
+18
-0
net/wireless/util.c
net/wireless/util.c
+2
-1
未找到文件。
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
浏览文件 @
20fb9e50
...
...
@@ -542,9 +542,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
if
(
changed
&
BSS_CHANGED_ARP_FILTER
)
{
/* Hardware ARP filter address list or state changed */
brcms_err
(
core
,
"%s: arp filtering: enabled %s, count %d"
" (implement)
\n
"
,
__func__
,
info
->
arp_filter_enabled
?
"true"
:
"false"
,
info
->
arp_addr_cnt
);
brcms_err
(
core
,
"%s: arp filtering: %d addresses"
" (implement)
\n
"
,
__func__
,
info
->
arp_addr_cnt
);
}
if
(
changed
&
BSS_CHANGED_QOS
)
{
...
...
drivers/net/wireless/iwlwifi/dvm/mac80211.c
浏览文件 @
20fb9e50
...
...
@@ -1154,6 +1154,7 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
}
static
void
iwlagn_mac_rssi_callback
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
)
{
struct
iwl_priv
*
priv
=
IWL_MAC80211_GET_DVM
(
hw
);
...
...
drivers/net/wireless/ti/wlcore/main.c
浏览文件 @
20fb9e50
...
...
@@ -4239,8 +4239,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
wlvif
->
sta
.
qos
=
bss_conf
->
qos
;
WARN_ON
(
wlvif
->
bss_type
!=
BSS_TYPE_STA_BSS
);
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
arp_filter_enabled
)
{
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
assoc
)
{
wlvif
->
ip_addr
=
addr
;
/*
* The template should have been configured only upon
...
...
include/linux/ieee80211.h
浏览文件 @
20fb9e50
...
...
@@ -1898,7 +1898,10 @@ enum ieee80211_sa_query_action {
/* AKM suite selectors */
#define WLAN_AKM_SUITE_8021X 0x000FAC01
#define WLAN_AKM_SUITE_PSK 0x000FAC02
#define WLAN_AKM_SUITE_SAE 0x000FAC08
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
#define WLAN_AKM_SUITE_TDLS 0x000FAC07
#define WLAN_AKM_SUITE_SAE 0x000FAC08
#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09
#define WLAN_MAX_KEY_LEN 32
...
...
include/net/cfg80211.h
浏览文件 @
20fb9e50
...
...
@@ -527,6 +527,26 @@ struct cfg80211_beacon_data {
size_t
probe_resp_len
;
};
struct
mac_address
{
u8
addr
[
ETH_ALEN
];
};
/**
* struct cfg80211_acl_data - Access control list data
*
* @acl_policy: ACL policy to be applied on the station's
entry specified by mac_addr
* @n_acl_entries: Number of MAC address entries passed
* @mac_addrs: List of MAC addresses of stations to be used for ACL
*/
struct
cfg80211_acl_data
{
enum
nl80211_acl_policy
acl_policy
;
int
n_acl_entries
;
/* Keep it last */
struct
mac_address
mac_addrs
[];
};
/**
* struct cfg80211_ap_settings - AP configuration
*
...
...
@@ -546,6 +566,8 @@ struct cfg80211_beacon_data {
* @inactivity_timeout: time in seconds to determine station's inactivity.
* @p2p_ctwindow: P2P CT Window
* @p2p_opp_ps: P2P opportunistic PS
* @acl: ACL configuration used by the drivers which has support for
* MAC address based access control
*/
struct
cfg80211_ap_settings
{
struct
cfg80211_chan_def
chandef
;
...
...
@@ -562,6 +584,7 @@ struct cfg80211_ap_settings {
int
inactivity_timeout
;
u8
p2p_ctwindow
;
bool
p2p_opp_ps
;
const
struct
cfg80211_acl_data
*
acl
;
};
/**
...
...
@@ -1796,6 +1819,13 @@ struct cfg80211_gtk_rekey_data {
*
* @start_p2p_device: Start the given P2P device.
* @stop_p2p_device: Stop the given P2P device.
*
* @set_mac_acl: Sets MAC address control list in AP and P2P GO mode.
* Parameters include ACL policy, an array of MAC address of stations
* and the number of MAC addresses. If there is already a list in driver
* this new list replaces the existing one. Driver has to clear its ACL
* when number of MAC addresses entries is passed as 0. Drivers which
* advertise the support for MAC based ACL have to implement this callback.
*/
struct
cfg80211_ops
{
int
(
*
suspend
)(
struct
wiphy
*
wiphy
,
struct
cfg80211_wowlan
*
wow
);
...
...
@@ -2016,6 +2046,9 @@ struct cfg80211_ops {
struct
wireless_dev
*
wdev
);
void
(
*
stop_p2p_device
)(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
);
int
(
*
set_mac_acl
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
const
struct
cfg80211_acl_data
*
params
);
};
/*
...
...
@@ -2181,10 +2214,6 @@ struct ieee80211_iface_combination {
u8
radar_detect_widths
;
};
struct
mac_address
{
u8
addr
[
ETH_ALEN
];
};
struct
ieee80211_txrx_stypes
{
u16
tx
,
rx
;
};
...
...
@@ -2325,6 +2354,9 @@ struct wiphy_wowlan_support {
* @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
* @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden.
* If null, then none can be over-ridden.
*
* @max_acl_mac_addrs: Maximum number of MAC addresses that the device
* supports for ACL.
*/
struct
wiphy
{
/* assign these fields before you register the wiphy */
...
...
@@ -2346,6 +2378,8 @@ struct wiphy {
/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
u16
interface_modes
;
u16
max_acl_mac_addrs
;
u32
flags
,
features
;
u32
ap_sme_capa
;
...
...
include/net/mac80211.h
浏览文件 @
20fb9e50
...
...
@@ -297,11 +297,9 @@ enum ieee80211_rssi_event {
* may filter ARP queries targeted for other addresses than listed here.
* The driver must allow ARP queries targeted for all address listed here
* to pass through. An empty list implies no ARP queries need to pass.
* @arp_addr_cnt: Number of addresses currently on the list.
* @arp_filter_enabled: Enable ARP filtering - if enabled, the hardware may
* filter ARP queries based on the @arp_addr_list, if disabled, the
* hardware must not perform any ARP filtering. Note, that the filter will
* be enabled also in promiscuous mode.
* @arp_addr_cnt: Number of addresses currently on the list. Note that this
* may be larger than %IEEE80211_BSS_ARP_ADDR_LIST_LEN (the arp_addr_list
* array size), it's up to the driver what to do in that case.
* @qos: This is a QoS-enabled BSS.
* @idle: This interface is idle. There's also a global idle flag in the
* hardware config which may be more appropriate depending on what
...
...
@@ -338,8 +336,7 @@ struct ieee80211_bss_conf {
u32
cqm_rssi_hyst
;
struct
cfg80211_chan_def
chandef
;
__be32
arp_addr_list
[
IEEE80211_BSS_ARP_ADDR_LIST_LEN
];
u8
arp_addr_cnt
;
bool
arp_filter_enabled
;
int
arp_addr_cnt
;
bool
qos
;
bool
idle
;
bool
ps
;
...
...
@@ -1630,6 +1627,10 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
* rekeying), it will not include a valid phase 1 key. The valid phase 1 key is
* provided by update_tkip_key only. The trigger that makes mac80211 call this
* handler is software decryption with wrap around of iv16.
*
* The set_default_unicast_key() call updates the default WEP key index
* configured to the hardware for WEP encryption type. This is required
* for devices that support offload of data packets (e.g. ARP responses).
*/
/**
...
...
@@ -2208,6 +2209,10 @@ enum ieee80211_rate_control_changed {
* After rekeying was done it should (for example during resume) notify
* userspace of the new replay counter using ieee80211_gtk_rekey_notify().
*
* @set_default_unicast_key: Set the default (unicast) key index, useful for
* WEP when the device sends data packets autonomously, e.g. for ARP
* offloading. The index can be 0-3, or -1 for unsetting it.
*
* @hw_scan: Ask the hardware to service the scan request, no need to start
* the scan state machine in stack. The scan must honour the channel
* configuration done by the regulatory agent in the wiphy's
...
...
@@ -2492,6 +2497,9 @@ enum ieee80211_rate_control_changed {
* driver's resume function returned 1, as this is just like an "inline"
* hardware restart. This callback may sleep.
*
* @ipv6_addr_change: IPv6 address assignment on the given interface changed.
* Currently, this is only called for managed or P2P client interfaces.
* This callback is optional; it must not sleep.
*/
struct
ieee80211_ops
{
void
(
*
tx
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2539,6 +2547,8 @@ struct ieee80211_ops {
void
(
*
set_rekey_data
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_gtk_rekey_data
*
data
);
void
(
*
set_default_unicast_key
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
int
idx
);
int
(
*
hw_scan
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_scan_request
*
req
);
void
(
*
cancel_hw_scan
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2623,6 +2633,7 @@ struct ieee80211_ops {
int
(
*
set_bitrate_mask
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
const
struct
cfg80211_bitrate_mask
*
mask
);
void
(
*
rssi_callback
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
);
void
(
*
allow_buffered_frames
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2665,6 +2676,12 @@ struct ieee80211_ops {
struct
ieee80211_chanctx_conf
*
ctx
);
void
(
*
restart_complete
)(
struct
ieee80211_hw
*
hw
);
#if IS_ENABLED(CONFIG_IPV6)
void
(
*
ipv6_addr_change
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
inet6_dev
*
idev
);
#endif
};
/**
...
...
include/uapi/linux/nl80211.h
浏览文件 @
20fb9e50
...
...
@@ -170,7 +170,8 @@
* %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
* %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
* %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
* %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
* %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
* %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
* The channel to use can be set on the interface or be given using the
* %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
* @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
...
...
@@ -586,6 +587,16 @@
* @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
* for IBSS or MESH vif.
*
* @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control.
* This is to be used with the drivers advertising the support of MAC
* address based access control. List of MAC addresses is passed in
* %NL80211_ATTR_MAC_ADDRS and ACL policy is passed in
* %NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it
* is not already done. The new list will replace any existing list. Driver
* will clear its ACL when the list of MAC addresses passed is empty. This
* command is used in AP/P2P GO mode. Driver has to make sure to clear its
* ACL list during %NL80211_CMD_STOP_AP.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
...
...
@@ -736,6 +747,8 @@ enum nl80211_commands {
NL80211_CMD_SET_MCAST_RATE
,
NL80211_CMD_SET_MAC_ACL
,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
...
...
@@ -1313,6 +1326,16 @@ enum nl80211_commands {
* @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
* defined in &enum nl80211_mesh_power_mode.
*
* @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
* carried in a u32 attribute
*
* @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
* MAC ACL.
*
* @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
* number of MAC addresses that a device can support for MAC
* ACL.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
...
...
@@ -1585,6 +1608,12 @@ enum nl80211_attrs {
NL80211_ATTR_LOCAL_MESH_POWER_MODE
,
NL80211_ATTR_ACL_POLICY
,
NL80211_ATTR_MAC_ADDRS
,
NL80211_ATTR_MAC_ACL_MAX
,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST
,
...
...
@@ -3248,7 +3277,7 @@ enum nl80211_probe_resp_offload_support_attr {
* enum nl80211_connect_failed_reason - connection request failed reasons
* @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be
* handled by the AP is reached.
* @NL80211_CONN_FAIL_BLOCKED_CLIENT: C
lient's MAC is in the AP's blocklist
.
* @NL80211_CONN_FAIL_BLOCKED_CLIENT: C
onnection request is rejected due to ACL
.
*/
enum
nl80211_connect_failed_reason
{
NL80211_CONN_FAIL_MAX_CLIENTS
,
...
...
@@ -3276,4 +3305,22 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_AP
=
1
<<
2
,
};
/**
* enum nl80211_acl_policy - access control policy
*
* Access control policy is applied on a MAC list set by
* %NL80211_CMD_START_AP and %NL80211_CMD_SET_MAC_ACL, to
* be used with %NL80211_ATTR_ACL_POLICY.
*
* @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
* listed in ACL, i.e. allow all the stations which are not listed
* in ACL to authenticate.
* @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow the stations which are listed
* in ACL, i.e. deny all the stations which are not listed in ACL.
*/
enum
nl80211_acl_policy
{
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED
,
NL80211_ACL_POLICY_DENY_UNLESS_LISTED
,
};
#endif
/* __LINUX_NL80211_H */
net/mac80211/agg-rx.c
浏览文件 @
20fb9e50
...
...
@@ -83,8 +83,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
if
(
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_RX_STOP
,
&
sta
->
sta
,
tid
,
NULL
,
0
))
sdata_info
(
sta
->
sdata
,
"HW problem - can not stop rx aggregation for tid %d
\n
"
,
tid
);
"HW problem - can not stop rx aggregation for
%pM
tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
/* check if this is a self generated aggregation halt */
if
(
initiator
==
WLAN_BACK_RECIPIENT
&&
tx
)
...
...
@@ -159,7 +159,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
}
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"rx session timer expired on tid %d
\n
"
,
(
u16
)
*
ptid
);
ht_dbg
(
sta
->
sdata
,
"RX session timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
(
u16
)
*
ptid
);
set_bit
(
*
ptid
,
sta
->
ampdu_mlme
.
tid_rx_timer_expired
);
ieee80211_queue_work
(
&
sta
->
local
->
hw
,
&
sta
->
ampdu_mlme
.
work
);
...
...
@@ -247,7 +248,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
status
=
WLAN_STATUS_REQUEST_DECLINED
;
if
(
test_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
))
{
ht_dbg
(
sta
->
sdata
,
"Suspend in progress - Denying ADDBA request
\n
"
);
ht_dbg
(
sta
->
sdata
,
"Suspend in progress - Denying ADDBA request (%pM tid %d)
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
end_no_lock
;
}
...
...
@@ -317,7 +320,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
ret
=
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_RX_START
,
&
sta
->
sta
,
tid
,
&
start_seq_num
,
0
);
ht_dbg
(
sta
->
sdata
,
"Rx A-MPDU request on tid %d result %d
\n
"
,
tid
,
ret
);
ht_dbg
(
sta
->
sdata
,
"Rx A-MPDU request on %pM tid %d result %d
\n
"
,
sta
->
sta
.
addr
,
tid
,
ret
);
if
(
ret
)
{
kfree
(
tid_agg_rx
->
reorder_buf
);
kfree
(
tid_agg_rx
->
reorder_time
);
...
...
net/mac80211/agg-tx.c
浏览文件 @
20fb9e50
...
...
@@ -296,7 +296,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
,
&
sta
->
sta
,
tid
,
NULL
,
0
);
WARN_ON_ONCE
(
ret
);
goto
remove_tid_tx
;
return
0
;
}
if
(
test_bit
(
HT_AGG_STATE_WANT_START
,
&
tid_tx
->
state
))
{
...
...
@@ -354,12 +354,15 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
*/
}
if
(
reason
==
AGG_STOP_DESTROY_STA
)
{
remove_tid_tx:
spin_lock_bh
(
&
sta
->
lock
);
ieee80211_remove_tid_tx
(
sta
,
tid
);
spin_unlock_bh
(
&
sta
->
lock
);
}
/*
* In the case of AGG_STOP_DESTROY_STA, the driver won't
* necessarily call ieee80211_stop_tx_ba_cb(), so this may
* seem like we can leave the tid_tx data pending forever.
* This is true, in a way, but "forever" is only until the
* station struct is actually destroyed. In the meantime,
* leaving it around ensures that we don't transmit packets
* to the driver on this TID which might confuse it.
*/
return
0
;
}
...
...
@@ -387,12 +390,13 @@ static void sta_addba_resp_timer_expired(unsigned long data)
test_bit
(
HT_AGG_STATE_RESPONSE_RECEIVED
,
&
tid_tx
->
state
))
{
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"timer expired on tid %d but we are not (or no longer) expecting addBA response there
\n
"
,
tid
);
"timer expired on
%pM
tid %d but we are not (or no longer) expecting addBA response there
\n
"
,
sta
->
sta
.
addr
,
tid
);
return
;
}
ht_dbg
(
sta
->
sdata
,
"addBA response timer expired on tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"addBA response timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
ieee80211_stop_tx_ba_session
(
&
sta
->
sta
,
tid
);
rcu_read_unlock
();
...
...
@@ -429,7 +433,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
&
sta
->
sta
,
tid
,
&
start_seq_num
,
0
);
if
(
ret
)
{
ht_dbg
(
sdata
,
"BA request denied - HW unavailable for tid %d
\n
"
,
tid
);
"BA request denied - HW unavailable for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
spin_lock_bh
(
&
sta
->
lock
);
ieee80211_agg_splice_packets
(
sdata
,
tid_tx
,
tid
);
ieee80211_assign_tid_tx
(
sta
,
tid
,
NULL
);
...
...
@@ -442,7 +447,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
/* activate the timer for the recipient's addBA response */
mod_timer
(
&
tid_tx
->
addba_resp_timer
,
jiffies
+
ADDBA_RESP_INTERVAL
);
ht_dbg
(
sdata
,
"activated addBA response timer on tid %d
\n
"
,
tid
);
ht_dbg
(
sdata
,
"activated addBA response timer on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
spin_lock_bh
(
&
sta
->
lock
);
sta
->
ampdu_mlme
.
last_addba_req_time
[
tid
]
=
jiffies
;
...
...
@@ -489,7 +495,8 @@ static void sta_tx_agg_session_timer_expired(unsigned long data)
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"tx session timer expired on tid %d
\n
"
,
(
u16
)
*
ptid
);
ht_dbg
(
sta
->
sdata
,
"tx session timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
(
u16
)
*
ptid
);
ieee80211_stop_tx_ba_session
(
&
sta
->
sta
,
*
ptid
);
}
...
...
@@ -525,7 +532,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
if
(
test_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
))
{
ht_dbg
(
sdata
,
"BA sessions blocked - Denying BA session request
\n
"
);
"BA sessions blocked - Denying BA session request %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
return
-
EINVAL
;
}
...
...
@@ -566,8 +574,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
time_before
(
jiffies
,
sta
->
ampdu_mlme
.
last_addba_req_time
[
tid
]
+
HT_AGG_RETRIES_PERIOD
))
{
ht_dbg
(
sdata
,
"BA request denied - waiting a grace period after %d failed requests on tid %u
\n
"
,
sta
->
ampdu_mlme
.
addba_req_num
[
tid
],
tid
);
"BA request denied - waiting a grace period after %d failed requests on
%pM
tid %u
\n
"
,
sta
->
ampdu_mlme
.
addba_req_num
[
tid
],
sta
->
sta
.
addr
,
tid
);
ret
=
-
EBUSY
;
goto
err_unlock_sta
;
}
...
...
@@ -576,8 +584,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
/* check if the TID is not in aggregation flow already */
if
(
tid_tx
||
sta
->
ampdu_mlme
.
tid_start_tx
[
tid
])
{
ht_dbg
(
sdata
,
"BA request denied - session is not idle on tid %u
\n
"
,
tid
);
"BA request denied - session is not idle on
%pM
tid %u
\n
"
,
sta
->
sta
.
addr
,
tid
);
ret
=
-
EAGAIN
;
goto
err_unlock_sta
;
}
...
...
@@ -632,7 +640,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
tid_tx
=
rcu_dereference_protected_tid_tx
(
sta
,
tid
);
ht_dbg
(
sta
->
sdata
,
"Aggregation is on for tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"Aggregation is on for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_TX_OPERATIONAL
,
...
...
@@ -802,7 +811,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
tid_tx
=
rcu_dereference_protected_tid_tx
(
sta
,
tid
);
if
(
!
tid_tx
||
!
test_bit
(
HT_AGG_STATE_STOPPING
,
&
tid_tx
->
state
))
{
ht_dbg
(
sdata
,
"unexpected callback to A-MPDU stop
\n
"
);
ht_dbg
(
sdata
,
"unexpected callback to A-MPDU stop for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
unlock_sta
;
}
...
...
@@ -861,13 +872,15 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
goto
out
;
if
(
mgmt
->
u
.
action
.
u
.
addba_resp
.
dialog_token
!=
tid_tx
->
dialog_token
)
{
ht_dbg
(
sta
->
sdata
,
"wrong addBA response token, tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"wrong addBA response token, %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
out
;
}
del_timer_sync
(
&
tid_tx
->
addba_resp_timer
);
ht_dbg
(
sta
->
sdata
,
"switched off addBA timer for tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"switched off addBA timer for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
/*
* addba_resp_timer may have fired before we got here, and
...
...
@@ -877,8 +890,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
if
(
test_bit
(
HT_AGG_STATE_WANT_STOP
,
&
tid_tx
->
state
)
||
test_bit
(
HT_AGG_STATE_STOPPING
,
&
tid_tx
->
state
))
{
ht_dbg
(
sta
->
sdata
,
"got addBA resp for tid %d but we already gave up
\n
"
,
tid
);
"got addBA resp for
%pM
tid %d but we already gave up
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
out
;
}
...
...
net/mac80211/driver-ops.h
浏览文件 @
20fb9e50
...
...
@@ -569,7 +569,8 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
check_sdata_in_driver
(
sdata
);
WARN_ON
(
changed
&
IEEE80211_RC_SUPP_RATES_CHANGED
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_ADHOC
);
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_ADHOC
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
));
trace_drv_sta_rc_update
(
local
,
sdata
,
sta
,
changed
);
if
(
local
->
ops
->
sta_rc_update
)
...
...
@@ -845,11 +846,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
}
static
inline
void
drv_rssi_callback
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
const
enum
ieee80211_rssi_event
event
)
{
trace_drv_rssi_callback
(
local
,
event
);
trace_drv_rssi_callback
(
local
,
sdata
,
event
);
if
(
local
->
ops
->
rssi_callback
)
local
->
ops
->
rssi_callback
(
&
local
->
hw
,
event
);
local
->
ops
->
rssi_callback
(
&
local
->
hw
,
&
sdata
->
vif
,
event
);
trace_drv_return_void
(
local
);
}
...
...
@@ -1020,4 +1022,32 @@ static inline void drv_restart_complete(struct ieee80211_local *local)
trace_drv_return_void
(
local
);
}
static
inline
void
drv_set_default_unicast_key
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
int
key_idx
)
{
check_sdata_in_driver
(
sdata
);
WARN_ON_ONCE
(
key_idx
<
-
1
||
key_idx
>
3
);
trace_drv_set_default_unicast_key
(
local
,
sdata
,
key_idx
);
if
(
local
->
ops
->
set_default_unicast_key
)
local
->
ops
->
set_default_unicast_key
(
&
local
->
hw
,
&
sdata
->
vif
,
key_idx
);
trace_drv_return_void
(
local
);
}
#if IS_ENABLED(CONFIG_IPV6)
static
inline
void
drv_ipv6_addr_change
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
struct
inet6_dev
*
idev
)
{
trace_drv_ipv6_addr_change
(
local
,
sdata
);
if
(
local
->
ops
->
ipv6_addr_change
)
local
->
ops
->
ipv6_addr_change
(
&
local
->
hw
,
&
sdata
->
vif
,
idev
);
trace_drv_return_void
(
local
);
}
#endif
#endif
/* __MAC80211_DRIVER_OPS */
net/mac80211/ieee80211_i.h
浏览文件 @
20fb9e50
...
...
@@ -747,8 +747,6 @@ struct ieee80211_sub_if_data {
struct
work_struct
work
;
struct
sk_buff_head
skb_queue
;
bool
arp_filter_state
;
u8
needed_rx_chains
;
enum
ieee80211_smps_mode
smps_mode
;
...
...
@@ -1129,6 +1127,7 @@ struct ieee80211_local {
struct
timer_list
dynamic_ps_timer
;
struct
notifier_block
network_latency_notifier
;
struct
notifier_block
ifa_notifier
;
struct
notifier_block
ifa6_notifier
;
/*
* The dynamic ps timeout configured from user space via WEXT -
...
...
net/mac80211/iface.c
浏览文件 @
20fb9e50
...
...
@@ -1574,9 +1574,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
/* initialise type-independent data */
sdata
->
wdev
.
wiphy
=
local
->
hw
.
wiphy
;
sdata
->
local
=
local
;
#ifdef CONFIG_INET
sdata
->
arp_filter_state
=
true
;
#endif
for
(
i
=
0
;
i
<
IEEE80211_FRAGMENT_MAX
;
i
++
)
skb_queue_head_init
(
&
sdata
->
fragments
[
i
].
skb_list
);
...
...
net/mac80211/key.c
浏览文件 @
20fb9e50
...
...
@@ -204,8 +204,11 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
if
(
idx
>=
0
&&
idx
<
NUM_DEFAULT_KEYS
)
key
=
key_mtx_dereference
(
sdata
->
local
,
sdata
->
keys
[
idx
]);
if
(
uni
)
if
(
uni
)
{
rcu_assign_pointer
(
sdata
->
default_unicast_key
,
key
);
drv_set_default_unicast_key
(
sdata
->
local
,
sdata
,
idx
);
}
if
(
multi
)
rcu_assign_pointer
(
sdata
->
default_multicast_key
,
key
);
...
...
net/mac80211/main.c
浏览文件 @
20fb9e50
...
...
@@ -23,6 +23,7 @@
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/addrconf.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
...
...
@@ -349,27 +350,19 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
/* Copy the addresses to the bss_conf list */
ifa
=
idev
->
ifa_list
;
while
(
c
<
IEEE80211_BSS_ARP_ADDR_LIST_LEN
&&
ifa
)
{
bss_conf
->
arp_addr_list
[
c
]
=
ifa
->
ifa_address
;
while
(
ifa
)
{
if
(
c
<
IEEE80211_BSS_ARP_ADDR_LIST_LEN
)
bss_conf
->
arp_addr_list
[
c
]
=
ifa
->
ifa_address
;
ifa
=
ifa
->
ifa_next
;
c
++
;
}
/* If not all addresses fit the list, disable filtering */
if
(
ifa
)
{
sdata
->
arp_filter_state
=
false
;
c
=
0
;
}
else
{
sdata
->
arp_filter_state
=
true
;
}
bss_conf
->
arp_addr_cnt
=
c
;
/* Configure driver only if associated (which also implies it is up) */
if
(
ifmgd
->
associated
)
{
bss_conf
->
arp_filter_enabled
=
sdata
->
arp_filter_state
;
if
(
ifmgd
->
associated
)
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_ARP_FILTER
);
}
mutex_unlock
(
&
ifmgd
->
mtx
);
...
...
@@ -377,6 +370,37 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
}
#endif
#if IS_ENABLED(CONFIG_IPV6)
static
int
ieee80211_ifa6_changed
(
struct
notifier_block
*
nb
,
unsigned
long
data
,
void
*
arg
)
{
struct
inet6_ifaddr
*
ifa
=
(
struct
inet6_ifaddr
*
)
arg
;
struct
inet6_dev
*
idev
=
ifa
->
idev
;
struct
net_device
*
ndev
=
ifa
->
idev
->
dev
;
struct
ieee80211_local
*
local
=
container_of
(
nb
,
struct
ieee80211_local
,
ifa6_notifier
);
struct
wireless_dev
*
wdev
=
ndev
->
ieee80211_ptr
;
struct
ieee80211_sub_if_data
*
sdata
;
/* Make sure it's our interface that got changed */
if
(
!
wdev
||
wdev
->
wiphy
!=
local
->
hw
.
wiphy
)
return
NOTIFY_DONE
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
ndev
);
/*
* For now only support station mode. This is mostly because
* doing AP would have to handle AP_VLAN in some way ...
*/
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
)
return
NOTIFY_DONE
;
drv_ipv6_addr_change
(
local
,
sdata
,
idev
);
return
NOTIFY_DONE
;
}
#endif
static
int
ieee80211_napi_poll
(
struct
napi_struct
*
napi
,
int
budget
)
{
struct
ieee80211_local
*
local
=
...
...
@@ -985,12 +1009,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto
fail_ifa
;
#endif
#if IS_ENABLED(CONFIG_IPV6)
local
->
ifa6_notifier
.
notifier_call
=
ieee80211_ifa6_changed
;
result
=
register_inet6addr_notifier
(
&
local
->
ifa6_notifier
);
if
(
result
)
goto
fail_ifa6
;
#endif
netif_napi_add
(
&
local
->
napi_dev
,
&
local
->
napi
,
ieee80211_napi_poll
,
local
->
hw
.
napi_weight
);
return
0
;
#if IS_ENABLED(CONFIG_IPV6)
fail_ifa6:
#ifdef CONFIG_INET
unregister_inetaddr_notifier
(
&
local
->
ifa_notifier
);
#endif
#endif
#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
fail_ifa:
pm_qos_remove_notifier
(
PM_QOS_NETWORK_LATENCY
,
&
local
->
network_latency_notifier
);
...
...
@@ -1026,6 +1063,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
#ifdef CONFIG_INET
unregister_inetaddr_notifier
(
&
local
->
ifa_notifier
);
#endif
#if IS_ENABLED(CONFIG_IPV6)
unregister_inet6addr_notifier
(
&
local
->
ifa6_notifier
);
#endif
rtnl_lock
();
...
...
net/mac80211/mesh_plink.c
浏览文件 @
20fb9e50
...
...
@@ -55,30 +55,6 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
sta
->
plink_retries
=
0
;
}
/*
* Allocate mesh sta entry and insert into station table
*/
static
struct
sta_info
*
mesh_plink_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
)
{
struct
sta_info
*
sta
;
if
(
sdata
->
local
->
num_sta
>=
MESH_MAX_PLINKS
)
return
NULL
;
sta
=
sta_info_alloc
(
sdata
,
hw_addr
,
GFP_KERNEL
);
if
(
!
sta
)
return
NULL
;
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTH
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_ASSOC
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTHORIZED
);
set_sta_flag
(
sta
,
WLAN_STA_WME
);
return
sta
;
}
/**
* mesh_set_ht_prot_mode - set correct HT protection mode
*
...
...
@@ -309,53 +285,27 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
return
err
;
}
/**
* mesh_peer_init - initialize new mesh peer and return resulting sta_info
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame
*
* call under RCU
*/
static
struct
sta_info
*
mesh_peer_init
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
static
void
mesh_sta_info_init
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sta_info
*
sta
,
struct
ieee802_11_elems
*
elems
,
bool
insert
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
enum
ieee80211_band
band
=
ieee80211_get_sdata_band
(
sdata
);
struct
ieee80211_supported_band
*
sband
;
u32
rates
,
basic_rates
=
0
;
struct
sta_info
*
sta
;
bool
insert
=
false
;
u32
rates
,
basic_rates
=
0
,
changed
=
0
;
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
rates
=
ieee80211_sta_get_rates
(
local
,
elems
,
band
,
&
basic_rates
);
sta
=
sta_info_get
(
sdata
,
addr
);
if
(
!
sta
)
{
/* Userspace handles peer allocation when security is enabled */
if
(
sdata
->
u
.
mesh
.
security
&
IEEE80211_MESH_SEC_AUTHED
)
{
cfg80211_notify_new_peer_candidate
(
sdata
->
dev
,
addr
,
elems
->
ie_start
,
elems
->
total_len
,
GFP_ATOMIC
);
return
NULL
;
}
sta
=
mesh_plink_alloc
(
sdata
,
addr
);
if
(
!
sta
)
return
NULL
;
insert
=
true
;
}
spin_lock_bh
(
&
sta
->
lock
);
sta
->
last_rx
=
jiffies
;
if
(
sta
->
plink_state
==
NL80211_PLINK_ESTAB
)
{
spin_unlock_bh
(
&
sta
->
lock
);
return
sta
;
}
/* rates and capabilities don't change during peering */
if
(
sta
->
plink_state
==
NL80211_PLINK_ESTAB
)
goto
out
;
if
(
sta
->
sta
.
supp_rates
[
band
]
!=
rates
)
changed
|=
IEEE80211_RC_SUPP_RATES_CHANGED
;
sta
->
sta
.
supp_rates
[
band
]
=
rates
;
if
(
elems
->
ht_cap_elem
&&
sdata
->
vif
.
bss_conf
.
chandef
.
width
!=
NL80211_CHAN_WIDTH_20_NOHT
)
...
...
@@ -374,27 +324,115 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
~
IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
ieee80211_ht_oper_to_chandef
(
sdata
->
vif
.
bss_conf
.
chandef
.
chan
,
elems
->
ht_operation
,
&
chandef
);
if
(
sta
->
ch_width
!=
chandef
.
width
)
changed
|=
IEEE80211_RC_BW_CHANGED
;
sta
->
ch_width
=
chandef
.
width
;
}
if
(
insert
)
rate_control_rate_init
(
sta
);
else
rate_control_rate_update
(
local
,
sband
,
sta
,
changed
);
out:
spin_unlock_bh
(
&
sta
->
lock
);
}
static
struct
sta_info
*
__mesh_sta_info_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
)
{
struct
sta_info
*
sta
;
if
(
insert
&&
sta_info_insert
(
sta
)
)
if
(
sdata
->
local
->
num_sta
>=
MESH_MAX_PLINKS
)
return
NULL
;
sta
=
sta_info_alloc
(
sdata
,
hw_addr
,
GFP_KERNEL
);
if
(
!
sta
)
return
NULL
;
sta
->
plink_state
=
NL80211_PLINK_LISTEN
;
init_timer
(
&
sta
->
plink_timer
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTH
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_ASSOC
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTHORIZED
);
set_sta_flag
(
sta
,
WLAN_STA_WME
);
return
sta
;
}
static
struct
sta_info
*
mesh_sta_info_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
{
struct
sta_info
*
sta
=
NULL
;
/* Userspace handles peer allocation when security is enabled */
if
(
sdata
->
u
.
mesh
.
security
&
IEEE80211_MESH_SEC_AUTHED
)
cfg80211_notify_new_peer_candidate
(
sdata
->
dev
,
addr
,
elems
->
ie_start
,
elems
->
total_len
,
GFP_KERNEL
);
else
sta
=
__mesh_sta_info_alloc
(
sdata
,
addr
);
return
sta
;
}
/*
* mesh_sta_info_get - return mesh sta info entry for @addr.
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame.
*
* Return existing or newly allocated sta_info under RCU read lock.
* (re)initialize with given IEs.
*/
static
struct
sta_info
*
mesh_sta_info_get
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
__acquires
(
RCU
)
{
struct
sta_info
*
sta
=
NULL
;
rcu_read_lock
();
sta
=
sta_info_get
(
sdata
,
addr
);
if
(
sta
)
{
mesh_sta_info_init
(
sdata
,
sta
,
elems
,
false
);
}
else
{
rcu_read_unlock
();
/* can't run atomic */
sta
=
mesh_sta_info_alloc
(
sdata
,
addr
,
elems
);
if
(
!
sta
)
{
rcu_read_lock
();
return
NULL
;
}
mesh_sta_info_init
(
sdata
,
sta
,
elems
,
true
);
if
(
sta_info_insert_rcu
(
sta
))
return
NULL
;
}
return
sta
;
}
/*
* mesh_neighbour_update - update or initialize new mesh neighbor.
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame
*
* Initiates peering if appropriate.
*/
void
mesh_neighbour_update
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
,
struct
ieee802_11_elems
*
elems
)
{
struct
sta_info
*
sta
;
rcu_read_lock
();
sta
=
mesh_peer_init
(
sdata
,
hw_addr
,
elems
);
sta
=
mesh_sta_info_get
(
sdata
,
hw_addr
,
elems
);
if
(
!
sta
)
goto
out
;
...
...
@@ -632,6 +670,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
(
ftype
==
WLAN_SP_MESH_PEERING_CLOSE
&&
ie_len
==
8
))
memcpy
(
&
llid
,
PLINK_GET_PLID
(
elems
.
peering
),
2
);
/* WARNING: Only for sta pointer, is dropped & re-acquired */
rcu_read_lock
();
sta
=
sta_info_get
(
sdata
,
mgmt
->
sa
);
...
...
@@ -735,8 +774,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
if
(
event
==
OPN_ACPT
)
{
rcu_read_unlock
();
/* allocate sta entry if necessary and update info */
sta
=
mesh_
peer_ini
t
(
sdata
,
mgmt
->
sa
,
&
elems
);
sta
=
mesh_
sta_info_ge
t
(
sdata
,
mgmt
->
sa
,
&
elems
);
if
(
!
sta
)
{
mpl_dbg
(
sdata
,
"Mesh plink: failed to init peer!
\n
"
);
rcu_read_unlock
();
...
...
net/mac80211/mlme.c
浏览文件 @
20fb9e50
...
...
@@ -1465,10 +1465,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
bss_info_changed
|=
BSS_CHANGED_CQM
;
/* Enable ARP filtering */
if
(
bss_conf
->
arp_filter_enabled
!=
sdata
->
arp_filter_state
)
{
bss_conf
->
arp_filter_enabled
=
sdata
->
arp_filter_state
;
if
(
bss_conf
->
arp_addr_cnt
)
bss_info_changed
|=
BSS_CHANGED_ARP_FILTER
;
}
ieee80211_bss_info_change_notify
(
sdata
,
bss_info_changed
);
...
...
@@ -1489,7 +1487,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sta_info
*
sta
;
u32
changed
=
0
;
ASSERT_MGD_MTX
(
ifmgd
);
...
...
@@ -1521,14 +1518,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
netif_tx_stop_all_queues
(
sdata
->
dev
);
netif_carrier_off
(
sdata
->
dev
);
mutex_lock
(
&
local
->
sta_mtx
);
sta
=
sta_info_get
(
sdata
,
ifmgd
->
bssid
);
if
(
sta
)
{
set_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
);
ieee80211_sta_tear_down_BA_sessions
(
sta
,
AGG_STOP_DESTROY_STA
);
}
mutex_unlock
(
&
local
->
sta_mtx
);
/*
* if we want to get out of ps before disassoc (why?) we have
* to do it before sending disassoc, as otherwise the null-packet
...
...
@@ -1582,10 +1571,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
cancel_work_sync
(
&
local
->
dynamic_ps_enable_work
);
/* Disable ARP filtering */
if
(
sdata
->
vif
.
bss_conf
.
arp_filter_enabled
)
{
sdata
->
vif
.
bss_conf
.
arp_filter_enabled
=
false
;
if
(
sdata
->
vif
.
bss_conf
.
arp_addr_cnt
)
changed
|=
BSS_CHANGED_ARP_FILTER
;
}
sdata
->
vif
.
bss_conf
.
qos
=
false
;
changed
|=
BSS_CHANGED_QOS
;
...
...
@@ -2608,12 +2595,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if
(
sig
>
ifmgd
->
rssi_max_thold
&&
(
last_sig
<=
ifmgd
->
rssi_min_thold
||
last_sig
==
0
))
{
ifmgd
->
last_ave_beacon_signal
=
sig
;
drv_rssi_callback
(
local
,
RSSI_EVENT_HIGH
);
drv_rssi_callback
(
local
,
sdata
,
RSSI_EVENT_HIGH
);
}
else
if
(
sig
<
ifmgd
->
rssi_min_thold
&&
(
last_sig
>=
ifmgd
->
rssi_max_thold
||
last_sig
==
0
))
{
ifmgd
->
last_ave_beacon_signal
=
sig
;
drv_rssi_callback
(
local
,
RSSI_EVENT_LOW
);
drv_rssi_callback
(
local
,
sdata
,
RSSI_EVENT_LOW
);
}
}
...
...
@@ -3169,23 +3156,22 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
if
(
!
ifmgd
->
associated
)
mutex_lock
(
&
ifmgd
->
mtx
);
if
(
!
ifmgd
->
associated
)
{
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
if
(
sdata
->
flags
&
IEEE80211_SDATA_DISCONNECT_RESUME
)
{
sdata
->
flags
&=
~
IEEE80211_SDATA_DISCONNECT_RESUME
;
mutex_lock
(
&
ifmgd
->
mtx
);
if
(
ifmgd
->
associated
)
{
mlme_dbg
(
sdata
,
"driver requested disconnect after resume
\n
"
);
ieee80211_sta_connection_lost
(
sdata
,
ifmgd
->
associated
->
bssid
,
WLAN_REASON_UNSPECIFIED
);
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
mlme_dbg
(
sdata
,
"driver requested disconnect after resume
\n
"
);
ieee80211_sta_connection_lost
(
sdata
,
ifmgd
->
associated
->
bssid
,
WLAN_REASON_UNSPECIFIED
);
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
mutex_unlock
(
&
ifmgd
->
mtx
);
if
(
test_and_clear_bit
(
TMR_RUNNING_TIMER
,
&
ifmgd
->
timers_running
))
add_timer
(
&
ifmgd
->
timer
);
...
...
net/mac80211/sta_info.c
浏览文件 @
20fb9e50
...
...
@@ -380,11 +380,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta_dbg
(
sdata
,
"Allocated STA %pM
\n
"
,
sta
->
sta
.
addr
);
#ifdef CONFIG_MAC80211_MESH
sta
->
plink_state
=
NL80211_PLINK_LISTEN
;
init_timer
(
&
sta
->
plink_timer
);
#endif
return
sta
;
}
...
...
net/mac80211/trace.h
浏览文件 @
20fb9e50
...
...
@@ -347,8 +347,11 @@ TRACE_EVENT(drv_bss_info_changed,
__field
(
s32
,
cqm_rssi_hyst
);
__field
(
u32
,
channel_width
);
__field
(
u32
,
channel_cfreq1
);
__dynamic_array
(
u32
,
arp_addr_list
,
info
->
arp_addr_cnt
);
__field
(
bool
,
arp_filter_enabled
);
__dynamic_array
(
u32
,
arp_addr_list
,
info
->
arp_addr_cnt
>
IEEE80211_BSS_ARP_ADDR_LIST_LEN
?
IEEE80211_BSS_ARP_ADDR_LIST_LEN
:
info
->
arp_addr_cnt
);
__field
(
int
,
arp_addr_cnt
);
__field
(
bool
,
qos
);
__field
(
bool
,
idle
);
__field
(
bool
,
ps
);
...
...
@@ -384,9 +387,11 @@ TRACE_EVENT(drv_bss_info_changed,
__entry
->
cqm_rssi_hyst
=
info
->
cqm_rssi_hyst
;
__entry
->
channel_width
=
info
->
chandef
.
width
;
__entry
->
channel_cfreq1
=
info
->
chandef
.
center_freq1
;
__entry
->
arp_addr_cnt
=
info
->
arp_addr_cnt
;
memcpy
(
__get_dynamic_array
(
arp_addr_list
),
info
->
arp_addr_list
,
sizeof
(
u32
)
*
info
->
arp_addr_cnt
);
__entry
->
arp_filter_enabled
=
info
->
arp_filter_enabled
;
sizeof
(
u32
)
*
(
info
->
arp_addr_cnt
>
IEEE80211_BSS_ARP_ADDR_LIST_LEN
?
IEEE80211_BSS_ARP_ADDR_LIST_LEN
:
info
->
arp_addr_cnt
));
__entry
->
qos
=
info
->
qos
;
__entry
->
idle
=
info
->
idle
;
__entry
->
ps
=
info
->
ps
;
...
...
@@ -1184,23 +1189,26 @@ TRACE_EVENT(drv_set_rekey_data,
TRACE_EVENT
(
drv_rssi_callback
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
enum
ieee80211_rssi_event
rssi_event
),
TP_ARGS
(
local
,
rssi_event
),
TP_ARGS
(
local
,
sdata
,
rssi_event
),
TP_STRUCT__entry
(
LOCAL_ENTRY
VIF_ENTRY
__field
(
u32
,
rssi_event
)
),
TP_fast_assign
(
LOCAL_ASSIGN
;
VIF_ASSIGN
;
__entry
->
rssi_event
=
rssi_event
;
),
TP_printk
(
LOCAL_PR_FMT
" rssi_event:%d"
,
LOCAL_PR_ARG
,
__entry
->
rssi_event
LOCAL_PR_FMT
VIF_PR_FMT
" rssi_event:%d"
,
LOCAL_PR_ARG
,
VIF_PR_ARG
,
__entry
->
rssi_event
)
);
...
...
@@ -1432,6 +1440,14 @@ DEFINE_EVENT(local_only_evt, drv_restart_complete,
TP_ARGS
(
local
)
);
#if IS_ENABLED(CONFIG_IPV6)
DEFINE_EVENT
(
local_sdata_evt
,
drv_ipv6_addr_change
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
),
TP_ARGS
(
local
,
sdata
)
);
#endif
/*
* Tracing for API calls that drivers call.
*/
...
...
@@ -1821,6 +1837,29 @@ TRACE_EVENT(stop_queue,
)
);
TRACE_EVENT
(
drv_set_default_unicast_key
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
int
key_idx
),
TP_ARGS
(
local
,
sdata
,
key_idx
),
TP_STRUCT__entry
(
LOCAL_ENTRY
VIF_ENTRY
__field
(
int
,
key_idx
)
),
TP_fast_assign
(
LOCAL_ASSIGN
;
VIF_ASSIGN
;
__entry
->
key_idx
=
key_idx
;
),
TP_printk
(
LOCAL_PR_FMT
VIF_PR_FMT
" key_idx:%d"
,
LOCAL_PR_ARG
,
VIF_PR_ARG
,
__entry
->
key_idx
)
);
#ifdef CONFIG_MAC80211_MESSAGE_TRACING
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg
...
...
net/mac80211/tx.c
浏览文件 @
20fb9e50
...
...
@@ -1787,16 +1787,16 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
break
;
/* fall through */
case
NL80211_IFTYPE_AP
:
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
goto
fail_rcu
;
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_FROMDS
);
/* DA BSSID SA */
memcpy
(
hdr
.
addr1
,
skb
->
data
,
ETH_ALEN
);
memcpy
(
hdr
.
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
memcpy
(
hdr
.
addr3
,
skb
->
data
+
ETH_ALEN
,
ETH_ALEN
);
hdrlen
=
24
;
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
goto
fail_rcu
;
band
=
chanctx_conf
->
def
.
chan
->
band
;
break
;
case
NL80211_IFTYPE_WDS
:
...
...
net/wireless/core.c
浏览文件 @
20fb9e50
...
...
@@ -478,6 +478,11 @@ int wiphy_register(struct wiphy *wiphy)
ETH_ALEN
)))
return
-
EINVAL
;
if
(
WARN_ON
(
wiphy
->
max_acl_mac_addrs
&&
(
!
(
wiphy
->
flags
&
WIPHY_FLAG_HAVE_AP_SME
)
||
!
rdev
->
ops
->
set_mac_acl
)))
return
-
EINVAL
;
if
(
wiphy
->
addresses
)
memcpy
(
wiphy
->
perm_addr
,
wiphy
->
addresses
[
0
].
addr
,
ETH_ALEN
);
...
...
net/wireless/nl80211.c
浏览文件 @
20fb9e50
...
...
@@ -365,6 +365,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[
NL80211_ATTR_SCAN_FLAGS
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_P2P_CTWINDOW
]
=
{
.
type
=
NLA_U8
},
[
NL80211_ATTR_P2P_OPPPS
]
=
{
.
type
=
NLA_U8
},
[
NL80211_ATTR_ACL_POLICY
]
=
{.
type
=
NLA_U32
},
[
NL80211_ATTR_MAC_ADDRS
]
=
{
.
type
=
NLA_NESTED
},
};
/* policy for the key attributes */
...
...
@@ -1268,6 +1270,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
dev
->
wiphy
.
ht_capa_mod_mask
))
goto
nla_put_failure
;
if
(
dev
->
wiphy
.
flags
&
WIPHY_FLAG_HAVE_AP_SME
&&
dev
->
wiphy
.
max_acl_mac_addrs
&&
nla_put_u32
(
msg
,
NL80211_ATTR_MAC_ACL_MAX
,
dev
->
wiphy
.
max_acl_mac_addrs
))
goto
nla_put_failure
;
return
genlmsg_end
(
msg
,
hdr
);
nla_put_failure:
...
...
@@ -2491,6 +2499,97 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
return
err
;
}
/* This function returns an error or the number of nested attributes */
static
int
validate_acl_mac_addrs
(
struct
nlattr
*
nl_attr
)
{
struct
nlattr
*
attr
;
int
n_entries
=
0
,
tmp
;
nla_for_each_nested
(
attr
,
nl_attr
,
tmp
)
{
if
(
nla_len
(
attr
)
!=
ETH_ALEN
)
return
-
EINVAL
;
n_entries
++
;
}
return
n_entries
;
}
/*
* This function parses ACL information and allocates memory for ACL data.
* On successful return, the calling function is responsible to free the
* ACL buffer returned by this function.
*/
static
struct
cfg80211_acl_data
*
parse_acl_data
(
struct
wiphy
*
wiphy
,
struct
genl_info
*
info
)
{
enum
nl80211_acl_policy
acl_policy
;
struct
nlattr
*
attr
;
struct
cfg80211_acl_data
*
acl
;
int
i
=
0
,
n_entries
,
tmp
;
if
(
!
wiphy
->
max_acl_mac_addrs
)
return
ERR_PTR
(
-
EOPNOTSUPP
);
if
(
!
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
])
return
ERR_PTR
(
-
EINVAL
);
acl_policy
=
nla_get_u32
(
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
]);
if
(
acl_policy
!=
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED
&&
acl_policy
!=
NL80211_ACL_POLICY_DENY_UNLESS_LISTED
)
return
ERR_PTR
(
-
EINVAL
);
if
(
!
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
])
return
ERR_PTR
(
-
EINVAL
);
n_entries
=
validate_acl_mac_addrs
(
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
]);
if
(
n_entries
<
0
)
return
ERR_PTR
(
n_entries
);
if
(
n_entries
>
wiphy
->
max_acl_mac_addrs
)
return
ERR_PTR
(
-
ENOTSUPP
);
acl
=
kzalloc
(
sizeof
(
*
acl
)
+
(
sizeof
(
struct
mac_address
)
*
n_entries
),
GFP_KERNEL
);
if
(
!
acl
)
return
ERR_PTR
(
-
ENOMEM
);
nla_for_each_nested
(
attr
,
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
],
tmp
)
{
memcpy
(
acl
->
mac_addrs
[
i
].
addr
,
nla_data
(
attr
),
ETH_ALEN
);
i
++
;
}
acl
->
n_acl_entries
=
n_entries
;
acl
->
acl_policy
=
acl_policy
;
return
acl
;
}
static
int
nl80211_set_mac_acl
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
net_device
*
dev
=
info
->
user_ptr
[
1
];
struct
cfg80211_acl_data
*
acl
;
int
err
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_P2P_GO
)
return
-
EOPNOTSUPP
;
if
(
!
dev
->
ieee80211_ptr
->
beacon_interval
)
return
-
EINVAL
;
acl
=
parse_acl_data
(
&
rdev
->
wiphy
,
info
);
if
(
IS_ERR
(
acl
))
return
PTR_ERR
(
acl
);
err
=
rdev_set_mac_acl
(
rdev
,
dev
,
acl
);
kfree
(
acl
);
return
err
;
}
static
int
nl80211_parse_beacon
(
struct
genl_info
*
info
,
struct
cfg80211_beacon_data
*
bcn
)
{
...
...
@@ -2734,6 +2833,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
if
(
err
)
return
err
;
if
(
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
])
{
params
.
acl
=
parse_acl_data
(
&
rdev
->
wiphy
,
info
);
if
(
IS_ERR
(
params
.
acl
))
return
PTR_ERR
(
params
.
acl
);
}
err
=
rdev_start_ap
(
rdev
,
dev
,
&
params
);
if
(
!
err
)
{
wdev
->
preset_chandef
=
params
.
chandef
;
...
...
@@ -2742,6 +2847,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
wdev
->
ssid_len
=
params
.
ssid_len
;
memcpy
(
wdev
->
ssid
,
params
.
ssid
,
wdev
->
ssid_len
);
}
kfree
(
params
.
acl
);
return
err
;
}
...
...
@@ -7876,6 +7984,14 @@ static struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV
|
NL80211_FLAG_NEED_RTNL
,
},
{
.
cmd
=
NL80211_CMD_SET_MAC_ACL
,
.
doit
=
nl80211_set_mac_acl
,
.
policy
=
nl80211_policy
,
.
flags
=
GENL_ADMIN_PERM
,
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV
|
NL80211_FLAG_NEED_RTNL
,
},
};
static
struct
genl_multicast_group
nl80211_mlme_mcgrp
=
{
...
...
net/wireless/rdev-ops.h
浏览文件 @
20fb9e50
...
...
@@ -875,4 +875,16 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
rdev
->
ops
->
stop_p2p_device
(
&
rdev
->
wiphy
,
wdev
);
trace_rdev_return_void
(
&
rdev
->
wiphy
);
}
static
inline
int
rdev_set_mac_acl
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_acl_data
*
params
)
{
int
ret
;
trace_rdev_set_mac_acl
(
&
rdev
->
wiphy
,
dev
,
params
);
ret
=
rdev
->
ops
->
set_mac_acl
(
&
rdev
->
wiphy
,
dev
,
params
);
trace_rdev_return_int
(
&
rdev
->
wiphy
,
ret
);
return
ret
;
}
#endif
/* __CFG80211_RDEV_OPS */
net/wireless/trace.h
浏览文件 @
20fb9e50
...
...
@@ -1767,6 +1767,24 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device,
TP_ARGS
(
wiphy
,
wdev
)
);
TRACE_EVENT
(
rdev_set_mac_acl
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
struct
net_device
*
netdev
,
struct
cfg80211_acl_data
*
params
),
TP_ARGS
(
wiphy
,
netdev
,
params
),
TP_STRUCT__entry
(
WIPHY_ENTRY
NETDEV_ENTRY
__field
(
u32
,
acl_policy
)
),
TP_fast_assign
(
WIPHY_ASSIGN
;
WIPHY_ASSIGN
;
__entry
->
acl_policy
=
params
->
acl_policy
;
),
TP_printk
(
WIPHY_PR_FMT
", "
NETDEV_PR_FMT
", acl policy: %d"
,
WIPHY_PR_ARG
,
NETDEV_PR_ARG
,
__entry
->
acl_policy
)
);
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
...
...
net/wireless/util.c
浏览文件 @
20fb9e50
...
...
@@ -1212,7 +1212,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
case
NL80211_IFTYPE_MESH_POINT
:
case
NL80211_IFTYPE_P2P_GO
:
case
NL80211_IFTYPE_WDS
:
radar_required
=
!!
(
chan
->
flags
&
IEEE80211_CHAN_RADAR
);
radar_required
=
!!
(
chan
&&
(
chan
->
flags
&
IEEE80211_CHAN_RADAR
));
break
;
case
NL80211_IFTYPE_P2P_CLIENT
:
case
NL80211_IFTYPE_STATION
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录