Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
a9908ebf
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看板
提交
a9908ebf
编写于
2月 18, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
上级
cfe41828
8c6d59ee
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
309 addition
and
334 deletion
+309
-334
Documentation/DocBook/80211.tmpl
Documentation/DocBook/80211.tmpl
+2
-2
net/mac80211/cfg.c
net/mac80211/cfg.c
+7
-7
net/mac80211/iface.c
net/mac80211/iface.c
+5
-3
net/mac80211/main.c
net/mac80211/main.c
+1
-2
net/mac80211/mesh.c
net/mac80211/mesh.c
+61
-55
net/mac80211/mesh.h
net/mac80211/mesh.h
+50
-55
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_hwmp.c
+34
-34
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_pathtbl.c
+46
-43
net/mac80211/mesh_plink.c
net/mac80211/mesh_plink.c
+67
-67
net/mac80211/mesh_sync.c
net/mac80211/mesh_sync.c
+16
-31
net/mac80211/rx.c
net/mac80211/rx.c
+6
-6
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+0
-2
net/mac80211/trace.h
net/mac80211/trace.h
+3
-3
net/mac80211/tx.c
net/mac80211/tx.c
+11
-15
net/wireless/nl80211.c
net/wireless/nl80211.c
+0
-9
未找到文件。
Documentation/DocBook/80211.tmpl
浏览文件 @
a9908ebf
...
...
@@ -107,8 +107,8 @@
!Finclude/net/cfg80211.h key_params
!Finclude/net/cfg80211.h survey_info_flags
!Finclude/net/cfg80211.h survey_info
!Finclude/net/cfg80211.h
beacon_parameters
!Finclude/net/cfg80211.h
plink_action
s
!Finclude/net/cfg80211.h
cfg80211_beacon_data
!Finclude/net/cfg80211.h
cfg80211_ap_setting
s
!Finclude/net/cfg80211.h station_parameters
!Finclude/net/cfg80211.h station_info_flags
!Finclude/net/cfg80211.h rate_info_flags
...
...
net/mac80211/cfg.c
浏览文件 @
a9908ebf
...
...
@@ -1500,13 +1500,13 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
return
-
ENOENT
;
}
err
=
mesh_path_add
(
dst
,
sdata
);
err
=
mesh_path_add
(
sdata
,
dst
);
if
(
err
)
{
rcu_read_unlock
();
return
err
;
}
mpath
=
mesh_path_lookup
(
dst
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
dst
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
-
ENXIO
;
...
...
@@ -1518,12 +1518,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
}
static
int
ieee80211_del_mpath
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
u8
*
dst
)
u8
*
dst
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
dst
)
return
mesh_path_del
(
dst
,
sdata
);
return
mesh_path_del
(
sdata
,
dst
);
mesh_path_flush_by_iface
(
sdata
);
return
0
;
...
...
@@ -1547,7 +1547,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
return
-
ENOENT
;
}
mpath
=
mesh_path_lookup
(
dst
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
dst
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
-
ENOENT
;
...
...
@@ -1611,7 +1611,7 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
dst
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
dst
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
-
ENOENT
;
...
...
@@ -1632,7 +1632,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
rcu_read_lock
();
mpath
=
mesh_path_lookup_by_idx
(
idx
,
sdata
);
mpath
=
mesh_path_lookup_by_idx
(
sdata
,
idx
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
-
ENOENT
;
...
...
net/mac80211/iface.c
浏览文件 @
a9908ebf
...
...
@@ -294,7 +294,8 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
}
}
if
((
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
)
||
if
((
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
)
||
!
(
sdata
->
local
->
hw
.
flags
&
IEEE80211_HW_QUEUE_CONTROL
))
{
sdata
->
vif
.
cab_queue
=
IEEE80211_INVAL_HW_QUEUE
;
return
0
;
...
...
@@ -695,6 +696,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
ieee80211_roc_purge
(
sdata
);
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
)
ieee80211_mgd_stop
(
sdata
);
/*
* Remove all stations associated with this interface.
*
...
...
@@ -782,8 +786,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
}
}
spin_unlock_irqrestore
(
&
ps
->
bc_buf
.
lock
,
flags
);
}
else
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
)
{
ieee80211_mgd_stop
(
sdata
);
}
if
(
going_down
)
...
...
net/mac80211/main.c
浏览文件 @
a9908ebf
...
...
@@ -1173,8 +1173,7 @@ static void __exit ieee80211_exit(void)
rc80211_minstrel_ht_exit
();
rc80211_minstrel_exit
();
if
(
mesh_allocated
)
ieee80211s_stop
();
ieee80211s_stop
();
ieee80211_iface_exit
();
...
...
net/mac80211/mesh.c
浏览文件 @
a9908ebf
...
...
@@ -17,7 +17,7 @@
#define TMR_RUNNING_MP 1
#define TMR_RUNNING_MPR 2
int
mesh_allocated
;
static
int
mesh_allocated
;
static
struct
kmem_cache
*
rm_cache
;
bool
mesh_action_is_path_sel
(
struct
ieee80211_mgmt
*
mgmt
)
...
...
@@ -36,6 +36,8 @@ void ieee80211s_init(void)
void
ieee80211s_stop
(
void
)
{
if
(
!
mesh_allocated
)
return
;
mesh_pathtbl_unregister
();
kmem_cache_destroy
(
rm_cache
);
}
...
...
@@ -90,24 +92,22 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
(
ifmsh
->
mesh_cc_id
==
ie
->
mesh_config
->
meshconf_congest
)
&&
(
ifmsh
->
mesh_sp_id
==
ie
->
mesh_config
->
meshconf_synch
)
&&
(
ifmsh
->
mesh_auth_id
==
ie
->
mesh_config
->
meshconf_auth
)))
goto
mismatch
;
return
false
;
ieee80211_sta_get_rates
(
local
,
ie
,
ieee80211_get_sdata_band
(
sdata
),
&
basic_rates
);
if
(
sdata
->
vif
.
bss_conf
.
basic_rates
!=
basic_rates
)
goto
mismatch
;
return
false
;
ieee80211_ht_oper_to_chandef
(
sdata
->
vif
.
bss_conf
.
chandef
.
chan
,
ie
->
ht_operation
,
&
sta_chan_def
);
if
(
!
cfg80211_chandef_compatible
(
&
sdata
->
vif
.
bss_conf
.
chandef
,
&
sta_chan_def
))
goto
mismatch
;
return
false
;
return
true
;
mismatch:
return
false
;
}
/**
...
...
@@ -118,7 +118,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
bool
mesh_peer_accepts_plinks
(
struct
ieee802_11_elems
*
ie
)
{
return
(
ie
->
mesh_config
->
meshconf_cap
&
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS
)
!=
0
;
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS
)
!=
0
;
}
/**
...
...
@@ -196,11 +196,12 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
if
(
!
sdata
->
u
.
mesh
.
rmc
)
return
;
for
(
i
=
0
;
i
<
RMC_BUCKETS
;
i
++
)
for
(
i
=
0
;
i
<
RMC_BUCKETS
;
i
++
)
{
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
i
],
list
)
{
list_del
(
&
p
->
list
);
kmem_cache_free
(
rm_cache
,
p
);
}
}
kfree
(
rmc
);
sdata
->
u
.
mesh
.
rmc
=
NULL
;
...
...
@@ -209,6 +210,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
/**
* mesh_rmc_check - Check frame in recent multicast cache and add if absent.
*
* @sdata: interface
* @sa: source address
* @mesh_hdr: mesh_header
*
...
...
@@ -218,8 +220,8 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
* received this frame lately. If the frame is not in the cache, it is added to
* it.
*/
int
mesh_rmc_check
(
u8
*
sa
,
struct
ieee80211s_hdr
*
mesh_hdr
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_rmc_check
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
sa
,
struct
ieee80211s_hdr
*
mesh_hdr
)
{
struct
mesh_rmc
*
rmc
=
sdata
->
u
.
mesh
.
rmc
;
u32
seqnum
=
0
;
...
...
@@ -233,12 +235,11 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
idx
],
list
)
{
++
entries
;
if
(
time_after
(
jiffies
,
p
->
exp_time
)
||
(
entries
==
RMC_QUEUE_MAX_LEN
)
)
{
entries
==
RMC_QUEUE_MAX_LEN
)
{
list_del
(
&
p
->
list
);
kmem_cache_free
(
rm_cache
,
p
);
--
entries
;
}
else
if
((
seqnum
==
p
->
seqnum
)
&&
(
ether_addr_equal
(
sa
,
p
->
sa
)))
}
else
if
((
seqnum
==
p
->
seqnum
)
&&
ether_addr_equal
(
sa
,
p
->
sa
))
return
-
1
;
}
...
...
@@ -253,8 +254,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
return
0
;
}
int
mesh_add_meshconf_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_meshconf_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u8
*
pos
,
neighbors
;
...
...
@@ -285,19 +286,18 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
/* Mesh capability */
*
pos
=
IEEE80211_MESHCONF_CAPAB_FORWARDING
;
*
pos
|=
ifmsh
->
accepting_plinks
?
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS
:
0x00
;
IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS
:
0x00
;
/* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */
*
pos
|=
ifmsh
->
ps_peers_deep_sleep
?
IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL
:
0x00
;
IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL
:
0x00
;
*
pos
++
|=
ifmsh
->
adjusting_tbtt
?
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING
:
0x00
;
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING
:
0x00
;
*
pos
++
=
0x00
;
return
0
;
}
int
mesh_add_meshid_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_meshid_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u8
*
pos
;
...
...
@@ -314,8 +314,8 @@ mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
return
0
;
}
int
mesh_add_awake_window_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
static
int
mesh_add_awake_window_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u8
*
pos
;
...
...
@@ -337,8 +337,8 @@ int mesh_add_awake_window_ie(struct sk_buff *skb,
return
0
;
}
int
mesh_add_vendor_ies
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_vendor_ies
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u8
offset
,
len
;
...
...
@@ -361,8 +361,7 @@ mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
return
0
;
}
int
mesh_add_rsn_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_rsn_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u8
len
=
0
;
...
...
@@ -390,8 +389,8 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
return
0
;
}
int
mesh_add_ds_params_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
static
int
mesh_add_ds_params_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_channel
*
chan
;
...
...
@@ -417,8 +416,8 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
return
0
;
}
int
mesh_add_ht_cap_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_ht_cap_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
enum
ieee80211_band
band
=
ieee80211_get_sdata_band
(
sdata
);
...
...
@@ -439,8 +438,8 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
return
0
;
}
int
mesh_add_ht_oper_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_add_ht_oper_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
...
...
@@ -475,6 +474,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
return
0
;
}
static
void
ieee80211_mesh_path_timer
(
unsigned
long
data
)
{
struct
ieee80211_sub_if_data
*
sdata
=
...
...
@@ -520,7 +520,7 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
/**
* ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
* @hdr:
802.11 frame header
* @hdr: 802.11 frame header
* @fc: frame control field
* @meshda: destination address in the mesh
* @meshsa: source address address in the mesh. Same as TA, as frame is
...
...
@@ -551,8 +551,8 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
/**
* ieee80211_new_mesh_header - create a new mesh header
* @meshhdr: uninitialized mesh header
* @sdata: mesh interface to be used
* @meshhdr: uninitialized mesh header
* @addr4or5: 1st address in the ae header, which may correspond to address 4
* (if addr6 is NULL) or address 5 (if addr6 is present). It may
* be NULL.
...
...
@@ -561,32 +561,38 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
*
* Return the header length.
*/
int
ieee80211_new_mesh_header
(
struct
ieee80211
s_hdr
*
meshhdr
,
struct
ieee80211_sub_if_data
*
sdata
,
char
*
addr4or5
,
char
*
addr6
)
int
ieee80211_new_mesh_header
(
struct
ieee80211
_sub_if_data
*
sdata
,
struct
ieee80211s_hdr
*
meshhdr
,
const
char
*
addr4or5
,
const
char
*
addr6
)
{
int
aelen
=
0
;
BUG_ON
(
!
addr4or5
&&
addr6
);
if
(
WARN_ON
(
!
addr4or5
&&
addr6
))
return
0
;
memset
(
meshhdr
,
0
,
sizeof
(
*
meshhdr
));
meshhdr
->
ttl
=
sdata
->
u
.
mesh
.
mshcfg
.
dot11MeshTTL
;
/* FIXME: racy -- TX on multiple queues can be concurrent */
put_unaligned
(
cpu_to_le32
(
sdata
->
u
.
mesh
.
mesh_seqnum
),
&
meshhdr
->
seqnum
);
sdata
->
u
.
mesh
.
mesh_seqnum
++
;
if
(
addr4or5
&&
!
addr6
)
{
meshhdr
->
flags
|=
MESH_FLAGS_AE_A4
;
aelen
+=
ETH_ALEN
;
memcpy
(
meshhdr
->
eaddr1
,
addr4or5
,
ETH_ALEN
);
return
2
*
ETH_ALEN
;
}
else
if
(
addr4or5
&&
addr6
)
{
meshhdr
->
flags
|=
MESH_FLAGS_AE_A5_A6
;
aelen
+=
2
*
ETH_ALEN
;
memcpy
(
meshhdr
->
eaddr1
,
addr4or5
,
ETH_ALEN
);
memcpy
(
meshhdr
->
eaddr2
,
addr6
,
ETH_ALEN
);
return
3
*
ETH_ALEN
;
}
return
6
+
aelen
;
return
ETH_ALEN
;
}
static
void
ieee80211_mesh_housekeeping
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_if_mesh
*
ifmsh
)
static
void
ieee80211_mesh_housekeeping
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u32
changed
;
ieee80211_sta_expire
(
sdata
,
IEEE80211_MESH_PEER_INACTIVITY_LIMIT
);
...
...
@@ -596,7 +602,8 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
ieee80211_mbss_info_change_notify
(
sdata
,
changed
);
mod_timer
(
&
ifmsh
->
housekeeping_timer
,
round_jiffies
(
jiffies
+
IEEE80211_MESH_HOUSEKEEPING_INTERVAL
));
round_jiffies
(
jiffies
+
IEEE80211_MESH_HOUSEKEEPING_INTERVAL
));
}
static
void
ieee80211_mesh_rootpath
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -708,7 +715,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
*
pos
++
=
0x0
;
if
(
ieee80211_add_srates_ie
(
sdata
,
skb
,
true
,
band
)
||
mesh_add_ds_params_ie
(
s
kb
,
sdata
))
mesh_add_ds_params_ie
(
s
data
,
skb
))
goto
out_free
;
bcn
->
head_len
=
skb
->
len
;
...
...
@@ -719,13 +726,13 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
bcn
->
tail
=
bcn
->
head
+
bcn
->
head_len
;
if
(
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
true
,
band
)
||
mesh_add_rsn_ie
(
s
kb
,
sdata
)
||
mesh_add_ht_cap_ie
(
s
kb
,
sdata
)
||
mesh_add_ht_oper_ie
(
s
kb
,
sdata
)
||
mesh_add_meshid_ie
(
s
kb
,
sdata
)
||
mesh_add_meshconf_ie
(
s
kb
,
sdata
)
||
mesh_add_awake_window_ie
(
s
kb
,
sdata
)
||
mesh_add_vendor_ies
(
s
kb
,
sdata
))
mesh_add_rsn_ie
(
s
data
,
skb
)
||
mesh_add_ht_cap_ie
(
s
data
,
skb
)
||
mesh_add_ht_oper_ie
(
s
data
,
skb
)
||
mesh_add_meshid_ie
(
s
data
,
skb
)
||
mesh_add_meshconf_ie
(
s
data
,
skb
)
||
mesh_add_awake_window_ie
(
s
data
,
skb
)
||
mesh_add_vendor_ies
(
s
data
,
skb
))
goto
out_free
;
bcn
->
tail_len
=
skb
->
len
;
...
...
@@ -918,7 +925,6 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
hdr
->
frame_control
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
IEEE80211_STYPE_PROBE_RESP
);
memcpy
(
hdr
->
da
,
mgmt
->
sa
,
ETH_ALEN
);
mpl_dbg
(
sdata
,
"sending probe resp. to %pM
\n
"
,
hdr
->
da
);
IEEE80211_SKB_CB
(
presp
)
->
flags
|=
IEEE80211_TX_INTFL_DONT_ENCRYPT
;
ieee80211_tx_skb
(
sdata
,
presp
);
out:
...
...
@@ -1039,7 +1045,7 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
mesh_mpp_table_grow
();
if
(
test_and_clear_bit
(
MESH_WORK_HOUSEKEEPING
,
&
ifmsh
->
wrkq_flags
))
ieee80211_mesh_housekeeping
(
sdata
,
ifmsh
);
ieee80211_mesh_housekeeping
(
sdata
);
if
(
test_and_clear_bit
(
MESH_WORK_ROOT
,
&
ifmsh
->
wrkq_flags
))
ieee80211_mesh_rootpath
(
sdata
);
...
...
net/mac80211/mesh.h
浏览文件 @
a9908ebf
...
...
@@ -26,12 +26,12 @@
* @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
* @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
* @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
*
number
* number
* @MESH_PATH_FIXED: the mesh path has been manually set and should not be
*
modified
* modified
* @MESH_PATH_RESOLVED: the mesh path can has been resolved
* @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
*
already queued up, waiting for the discovery process to start.
*
already queued up, waiting for the discovery process to start.
*
* MESH_PATH_RESOLVED is used by the mesh path timer to
* decide when to stop or cancel the mesh path discovery.
...
...
@@ -73,16 +73,16 @@ enum mesh_deferred_task_flags {
* @dst: mesh path destination mac address
* @sdata: mesh subif
* @next_hop: mesh neighbor to which frames for this destination will be
*
forwarded
* forwarded
* @timer: mesh path discovery timer
* @frame_queue: pending queue for frames sent to this destination while the
*
path is unresolved
* path is unresolved
* @sn: target sequence number
* @metric: current metric to this destination
* @hop_count: hops to destination
* @exp_time: in jiffies, when the path will expire or when it expired
* @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
*
retry
* retry
* @discovery_retries: number of discovery retries
* @flags: mesh path flags, as specified on &enum mesh_path_flags
* @state_lock: mesh path state lock used to protect changes to the
...
...
@@ -206,38 +206,33 @@ struct mesh_rmc {
/* Various */
int
ieee80211_fill_mesh_addresses
(
struct
ieee80211_hdr
*
hdr
,
__le16
*
fc
,
const
u8
*
da
,
const
u8
*
sa
);
int
ieee80211_new_mesh_header
(
struct
ieee80211
s_hdr
*
meshhdr
,
struct
ieee80211_sub_if_data
*
sdata
,
char
*
addr4or5
,
char
*
addr6
);
int
mesh_rmc_check
(
u8
*
addr
,
struct
ieee80211s_hdr
*
mesh_hdr
,
struct
ieee80211_sub_if_data
*
sdata
);
int
ieee80211_new_mesh_header
(
struct
ieee80211
_sub_if_data
*
sdata
,
struct
ieee80211s_hdr
*
meshhdr
,
const
char
*
addr4or5
,
const
char
*
addr6
);
int
mesh_rmc_check
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
addr
,
struct
ieee80211s_hdr
*
mesh_hdr
);
bool
mesh_matches_local
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee802_11_elems
*
ie
);
void
mesh_ids_set_default
(
struct
ieee80211_if_mesh
*
mesh
);
void
mesh_mgmt_ies_add
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_meshconf_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_meshid_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_rsn_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_awake_window_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_vendor_ies
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_ds_params_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_ht_cap_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_add_ht_oper_ie
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_mgmt_ies_add
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_meshconf_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_meshid_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_rsn_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_vendor_ies
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_ht_cap_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_add_ht_oper_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
void
mesh_rmc_free
(
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_rmc_init
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211s_init
(
void
);
void
ieee80211s_update_metric
(
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
,
struct
sk_buff
*
skb
);
void
ieee80211s_stop
(
void
);
struct
sta_info
*
sta
,
struct
sk_buff
*
skb
);
void
ieee80211_mesh_init_sdata
(
struct
ieee80211_sub_if_data
*
sdata
);
int
ieee80211_start_mesh
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_stop_mesh
(
struct
ieee80211_sub_if_data
*
sdata
);
...
...
@@ -263,31 +258,32 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
struct
ieee802_11_elems
*
elems
);
/* Mesh paths */
int
mesh_nexthop_lookup
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_nexthop_resolve
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_nexthop_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
int
mesh_nexthop_resolve
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
void
mesh_path_start_discovery
(
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mesh_path_lookup
(
const
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mpp_path_lookup
(
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mpp_path_add
(
u8
*
dst
,
u8
*
mpp
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mesh_path_lookup_by_idx
(
int
idx
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mesh_path_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
);
struct
mesh_path
*
mpp_path_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
);
int
mpp_path_add
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
,
const
u8
*
mpp
);
struct
mesh_path
*
mesh_path_lookup_by_idx
(
struct
ieee80211_sub_if_data
*
sdata
,
int
idx
);
void
mesh_path_fix_nexthop
(
struct
mesh_path
*
mpath
,
struct
sta_info
*
next_hop
);
void
mesh_path_expire
(
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_rx_path_sel_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
);
int
mesh_path_add
(
const
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
);
int
mesh_path_add
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
);
int
mesh_path_add_gate
(
struct
mesh_path
*
mpath
);
int
mesh_path_send_to_gates
(
struct
mesh_path
*
mpath
);
int
mesh_gate_num
(
struct
ieee80211_sub_if_data
*
sdata
);
/* Mesh plinks */
void
mesh_neighbour_update
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
,
struct
ieee802_11_elems
*
ie
);
u8
*
hw_addr
,
struct
ieee802_11_elems
*
ie
);
bool
mesh_peer_accepts_plinks
(
struct
ieee802_11_elems
*
ie
);
u32
mesh_accept_plinks_update
(
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_plink_broken
(
struct
sta_info
*
sta
);
...
...
@@ -304,19 +300,19 @@ void mesh_sta_cleanup(struct sta_info *sta);
void
mesh_mpath_table_grow
(
void
);
void
mesh_mpp_table_grow
(
void
);
/* Mesh paths */
int
mesh_path_error_tx
(
u8
ttl
,
const
u8
*
target
,
__le32
target_sn
,
__le16
target_rcode
,
const
u8
*
ra
,
struct
ieee80211_sub_if_data
*
sdat
a
);
int
mesh_path_error_tx
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
ttl
,
const
u8
*
target
,
__le32
target_sn
,
__le16
target_rcode
,
const
u8
*
r
a
);
void
mesh_path_assign_nexthop
(
struct
mesh_path
*
mpath
,
struct
sta_info
*
sta
);
void
mesh_path_flush_pending
(
struct
mesh_path
*
mpath
);
void
mesh_path_tx_pending
(
struct
mesh_path
*
mpath
);
int
mesh_pathtbl_init
(
void
);
void
mesh_pathtbl_unregister
(
void
);
int
mesh_path_del
(
u8
*
addr
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mesh_path_del
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
addr
);
void
mesh_path_timer
(
unsigned
long
data
);
void
mesh_path_flush_by_nexthop
(
struct
sta_info
*
sta
);
void
mesh_path_discard_frame
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_path_discard_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
);
void
mesh_path_quiesce
(
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_path_restart
(
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_path_tx_root_frame
(
struct
ieee80211_sub_if_data
*
sdata
);
...
...
@@ -325,8 +321,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
extern
int
mesh_paths_generation
;
#ifdef CONFIG_MAC80211_MESH
extern
int
mesh_allocated
;
static
inline
u32
mesh_plink_inc_estab_count
(
struct
ieee80211_sub_if_data
*
sdata
)
{
...
...
@@ -371,8 +365,8 @@ void mesh_plink_quiesce(struct sta_info *sta);
void
mesh_plink_restart
(
struct
sta_info
*
sta
);
void
mesh_path_flush_by_iface
(
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_sync_adjust_tbtt
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211s_stop
(
void
);
#else
#define mesh_allocated 0
static
inline
void
ieee80211_mesh_notify_scan_completed
(
struct
ieee80211_local
*
local
)
{}
static
inline
void
ieee80211_mesh_quiesce
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -385,6 +379,7 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
{
return
false
;
}
static
inline
void
mesh_path_flush_by_iface
(
struct
ieee80211_sub_if_data
*
sdata
)
{}
static
inline
void
ieee80211s_stop
(
void
)
{}
#endif
#endif
/* IEEE80211S_H */
net/mac80211/mesh_hwmp.c
浏览文件 @
a9908ebf
...
...
@@ -238,9 +238,9 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
* also acquires in the TX path. To avoid a deadlock we don't transmit the
* frame directly but add it to the pending queue instead.
*/
int
mesh_path_error_tx
(
u8
ttl
,
const
u8
*
target
,
__le32
target_sn
,
__le16
target_rcode
,
const
u8
*
ra
,
struct
ieee80211_sub_if_data
*
sdat
a
)
int
mesh_path_error_tx
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
ttl
,
const
u8
*
target
,
__le32
target_sn
,
__le16
target_rcode
,
const
u8
*
r
a
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sk_buff
*
skb
;
...
...
@@ -430,7 +430,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
process
=
false
;
fresh_info
=
false
;
}
else
{
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
mpath
)
{
spin_lock_bh
(
&
mpath
->
state_lock
);
if
(
mpath
->
flags
&
MESH_PATH_FIXED
)
...
...
@@ -445,8 +445,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
}
}
}
else
{
mesh_path_add
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mesh_path_add
(
sdata
,
orig_addr
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
0
;
...
...
@@ -478,7 +478,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
else
{
fresh_info
=
true
;
mpath
=
mesh_path_lookup
(
ta
,
sda
ta
);
mpath
=
mesh_path_lookup
(
sdata
,
ta
);
if
(
mpath
)
{
spin_lock_bh
(
&
mpath
->
state_lock
);
if
((
mpath
->
flags
&
MESH_PATH_FIXED
)
||
...
...
@@ -486,8 +486,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
(
last_hop_metric
>
mpath
->
metric
)))
fresh_info
=
false
;
}
else
{
mesh_path_add
(
ta
,
sda
ta
);
mpath
=
mesh_path_lookup
(
ta
,
sda
ta
);
mesh_path_add
(
sdata
,
ta
);
mpath
=
mesh_path_lookup
(
sdata
,
ta
);
if
(
!
mpath
)
{
rcu_read_unlock
();
return
0
;
...
...
@@ -553,7 +553,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
}
else
if
(
is_broadcast_ether_addr
(
target_addr
)
&&
(
target_flags
&
IEEE80211_PREQ_TO_FLAG
))
{
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
mpath
)
{
if
(
flags
&
IEEE80211_PREQ_PROACTIVE_PREP_FLAG
)
{
reply
=
true
;
...
...
@@ -568,7 +568,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock
();
}
else
{
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
target_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
target_addr
);
if
(
mpath
)
{
if
((
!
(
mpath
->
flags
&
MESH_PATH_SN_VALID
))
||
SN_LT
(
mpath
->
sn
,
target_sn
))
{
...
...
@@ -678,7 +678,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
}
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
mpath
)
spin_lock_bh
(
&
mpath
->
state_lock
);
else
...
...
@@ -736,7 +736,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
target_rcode
=
PERR_IE_TARGET_RCODE
(
perr_elem
);
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
target_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
target_addr
);
if
(
mpath
)
{
struct
sta_info
*
sta
;
...
...
@@ -751,9 +751,10 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
spin_unlock_bh
(
&
mpath
->
state_lock
);
if
(
!
ifmsh
->
mshcfg
.
dot11MeshForwarding
)
goto
endperr
;
mesh_path_error_tx
(
ttl
,
target_addr
,
cpu_to_le32
(
target_sn
),
mesh_path_error_tx
(
sdata
,
ttl
,
target_addr
,
cpu_to_le32
(
target_sn
),
cpu_to_le16
(
target_rcode
),
broadcast_addr
,
sdata
);
broadcast_addr
);
}
else
spin_unlock_bh
(
&
mpath
->
state_lock
);
}
...
...
@@ -801,10 +802,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
metric_txsta
=
airtime_link_metric_get
(
local
,
sta
);
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
!
mpath
)
{
mesh_path_add
(
orig_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
orig_addr
,
sdata
);
mesh_path_add
(
sdata
,
orig_addr
);
mpath
=
mesh_path_lookup
(
sdata
,
orig_addr
);
if
(
!
mpath
)
{
rcu_read_unlock
();
sdata
->
u
.
mesh
.
mshstats
.
dropped_frames_no_route
++
;
...
...
@@ -861,8 +862,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
void
mesh_rx_path_sel_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
)
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
)
{
struct
ieee802_11_elems
elems
;
size_t
baselen
;
...
...
@@ -1006,7 +1006,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
spin_unlock_bh
(
&
ifmsh
->
mesh_preq_queue_lock
);
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
preq_node
->
dst
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
preq_node
->
dst
);
if
(
!
mpath
)
goto
enddiscovery
;
...
...
@@ -1076,8 +1076,8 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
* Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
* skb is freeed here if no mpath could be allocated.
*/
int
mesh_nexthop_resolve
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_nexthop_resolve
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
...
...
@@ -1091,17 +1091,17 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
return
0
;
rcu_read_lock
();
err
=
mesh_nexthop_lookup
(
s
kb
,
sdata
);
err
=
mesh_nexthop_lookup
(
s
data
,
skb
);
if
(
!
err
)
goto
endlookup
;
/* no nexthop found, start resolving */
mpath
=
mesh_path_lookup
(
target_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
target_addr
);
if
(
!
mpath
)
{
mesh_path_add
(
target_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
target_addr
,
sdata
);
mesh_path_add
(
sdata
,
target_addr
);
mpath
=
mesh_path_lookup
(
sdata
,
target_addr
);
if
(
!
mpath
)
{
mesh_path_discard_frame
(
s
kb
,
sdata
);
mesh_path_discard_frame
(
s
data
,
skb
);
err
=
-
ENOSPC
;
goto
endlookup
;
}
...
...
@@ -1118,12 +1118,13 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
skb_queue_tail
(
&
mpath
->
frame_queue
,
skb
);
err
=
-
ENOENT
;
if
(
skb_to_free
)
mesh_path_discard_frame
(
s
kb_to_free
,
sdata
);
mesh_path_discard_frame
(
s
data
,
skb_to_free
);
endlookup:
rcu_read_unlock
();
return
err
;
}
/**
* mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
* this function is considered "using" the associated mpath, so preempt a path
...
...
@@ -1134,8 +1135,8 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
*
* Returns: 0 if the next hop was found. Nonzero otherwise.
*/
int
mesh_nexthop_lookup
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_nexthop_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
struct
mesh_path
*
mpath
;
struct
sta_info
*
next_hop
;
...
...
@@ -1144,7 +1145,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
int
err
=
-
ENOENT
;
rcu_read_lock
();
mpath
=
mesh_path_lookup
(
target_addr
,
sdata
);
mpath
=
mesh_path_lookup
(
sdata
,
target_addr
);
if
(
!
mpath
||
!
(
mpath
->
flags
&
MESH_PATH_ACTIVE
))
goto
endlookup
;
...
...
@@ -1203,8 +1204,7 @@ void mesh_path_timer(unsigned long data)
}
}
void
mesh_path_tx_root_frame
(
struct
ieee80211_sub_if_data
*
sdata
)
void
mesh_path_tx_root_frame
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
u32
interval
=
ifmsh
->
mshcfg
.
dot11MeshHWMPRannInterval
;
...
...
net/mac80211/mesh_pathtbl.c
浏览文件 @
a9908ebf
...
...
@@ -24,9 +24,12 @@
/* Keep the mean chain length below this constant */
#define MEAN_CHAIN_LEN 2
#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \
time_after(jiffies, mpath->exp_time) && \
!(mpath->flags & MESH_PATH_FIXED))
static
inline
bool
mpath_expired
(
struct
mesh_path
*
mpath
)
{
return
(
mpath
->
flags
&
MESH_PATH_ACTIVE
)
&&
time_after
(
jiffies
,
mpath
->
exp_time
)
&&
!
(
mpath
->
flags
&
MESH_PATH_FIXED
);
}
struct
mpath_node
{
struct
hlist_node
list
;
...
...
@@ -185,8 +188,8 @@ static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata,
struct
mesh_table
*
tbl
)
{
/* Use last four bytes of hw addr and interface index as hash index */
return
jhash_2words
(
*
(
u32
*
)(
addr
+
2
),
sdata
->
dev
->
ifindex
,
tbl
->
hash_rnd
)
&
tbl
->
hash_mask
;
return
jhash_2words
(
*
(
u32
*
)(
addr
+
2
),
sdata
->
dev
->
ifindex
,
tbl
->
hash_rnd
)
&
tbl
->
hash_mask
;
}
...
...
@@ -339,7 +342,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
mpath
=
node
->
mpath
;
if
(
mpath
->
sdata
==
sdata
&&
ether_addr_equal
(
dst
,
mpath
->
dst
))
{
if
(
MPATH_EXPIRED
(
mpath
))
{
if
(
mpath_expired
(
mpath
))
{
spin_lock_bh
(
&
mpath
->
state_lock
);
mpath
->
flags
&=
~
MESH_PATH_ACTIVE
;
spin_unlock_bh
(
&
mpath
->
state_lock
);
...
...
@@ -352,20 +355,21 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
/**
* mesh_path_lookup - look up a path in the mesh path table
* @dst: hardware address (ETH_ALEN length) of destination
* @sdata: local subif
* @dst: hardware address (ETH_ALEN length) of destination
*
* Returns: pointer to the mesh path structure, or NULL if not found
*
* Locking: must be called within a read rcu section.
*/
struct
mesh_path
*
mesh_path_lookup
(
const
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
)
struct
mesh_path
*
mesh_path_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
)
{
return
mpath_lookup
(
rcu_dereference
(
mesh_paths
),
dst
,
sdata
);
}
struct
mesh_path
*
mpp_path_lookup
(
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
)
struct
mesh_path
*
mpp_path_lookup
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
)
{
return
mpath_lookup
(
rcu_dereference
(
mpp_paths
),
dst
,
sdata
);
}
...
...
@@ -380,7 +384,8 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
*
* Locking: must be called within a read rcu section.
*/
struct
mesh_path
*
mesh_path_lookup_by_idx
(
int
idx
,
struct
ieee80211_sub_if_data
*
sdata
)
struct
mesh_path
*
mesh_path_lookup_by_idx
(
struct
ieee80211_sub_if_data
*
sdata
,
int
idx
)
{
struct
mesh_table
*
tbl
=
rcu_dereference
(
mesh_paths
);
struct
mpath_node
*
node
;
...
...
@@ -392,7 +397,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
if
(
sdata
&&
node
->
mpath
->
sdata
!=
sdata
)
continue
;
if
(
j
++
==
idx
)
{
if
(
MPATH_EXPIRED
(
node
->
mpath
))
{
if
(
mpath_expired
(
node
->
mpath
))
{
spin_lock_bh
(
&
node
->
mpath
->
state_lock
);
node
->
mpath
->
flags
&=
~
MESH_PATH_ACTIVE
;
spin_unlock_bh
(
&
node
->
mpath
->
state_lock
);
...
...
@@ -436,11 +441,10 @@ int mesh_path_add_gate(struct mesh_path *mpath)
spin_lock_bh
(
&
tbl
->
gates_lock
);
hlist_add_head_rcu
(
&
new_gate
->
list
,
tbl
->
known_gates
);
spin_unlock_bh
(
&
tbl
->
gates_lock
);
rcu_read_unlock
();
mpath_dbg
(
mpath
->
sdata
,
"Mesh path: Recorded new gate: %pM. %d known gates
\n
"
,
mpath
->
dst
,
mpath
->
sdata
->
u
.
mesh
.
num_gates
);
return
0
;
err
=
0
;
err_rcu:
rcu_read_unlock
();
return
err
;
...
...
@@ -451,30 +455,27 @@ int mesh_path_add_gate(struct mesh_path *mpath)
* @tbl: table which holds our list of known gates
* @mpath: gate mpath
*
* Returns: 0 on success
*
* Locking: must be called inside rcu_read_lock() section
*/
static
int
mesh_gate_del
(
struct
mesh_table
*
tbl
,
struct
mesh_path
*
mpath
)
static
void
mesh_gate_del
(
struct
mesh_table
*
tbl
,
struct
mesh_path
*
mpath
)
{
struct
mpath_node
*
gate
;
struct
hlist_node
*
p
,
*
q
;
hlist_for_each_entry_safe
(
gate
,
p
,
q
,
tbl
->
known_gates
,
list
)
if
(
gate
->
mpath
==
mpath
)
{
spin_lock_bh
(
&
tbl
->
gates_lock
);
hlist_del_rcu
(
&
gate
->
list
);
kfree_rcu
(
gate
,
rcu
);
spin_unlock_bh
(
&
tbl
->
gates_lock
);
mpath
->
sdata
->
u
.
mesh
.
num_gates
--
;
mpath
->
is_gate
=
false
;
mpath_dbg
(
mpath
->
sdata
,
"Mesh path: Deleted gate: %pM. %d known gates
\n
"
,
mpath
->
dst
,
mpath
->
sdata
->
u
.
mesh
.
num_gates
);
break
;
}
return
0
;
hlist_for_each_entry_safe
(
gate
,
p
,
q
,
tbl
->
known_gates
,
list
)
{
if
(
gate
->
mpath
!=
mpath
)
continue
;
spin_lock_bh
(
&
tbl
->
gates_lock
);
hlist_del_rcu
(
&
gate
->
list
);
kfree_rcu
(
gate
,
rcu
);
spin_unlock_bh
(
&
tbl
->
gates_lock
);
mpath
->
sdata
->
u
.
mesh
.
num_gates
--
;
mpath
->
is_gate
=
false
;
mpath_dbg
(
mpath
->
sdata
,
"Mesh path: Deleted gate: %pM. %d known gates
\n
"
,
mpath
->
dst
,
mpath
->
sdata
->
u
.
mesh
.
num_gates
);
break
;
}
}
/**
...
...
@@ -488,14 +489,14 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
/**
* mesh_path_add - allocate and add a new path to the mesh path table
* @
addr
: destination address of the path (ETH_ALEN length)
* @
dst
: destination address of the path (ETH_ALEN length)
* @sdata: local subif
*
* Returns: 0 on success
*
* State: the initial state of the new path is set to 0
*/
int
mesh_path_add
(
const
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_path_add
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
...
...
@@ -630,7 +631,8 @@ void mesh_mpp_table_grow(void)
write_unlock_bh
(
&
pathtbl_resize_lock
);
}
int
mpp_path_add
(
u8
*
dst
,
u8
*
mpp
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mpp_path_add
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
dst
,
const
u8
*
mpp
)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
...
...
@@ -739,9 +741,10 @@ void mesh_plink_broken(struct sta_info *sta)
mpath
->
flags
&=
~
MESH_PATH_ACTIVE
;
++
mpath
->
sn
;
spin_unlock_bh
(
&
mpath
->
state_lock
);
mesh_path_error_tx
(
sdata
->
u
.
mesh
.
mshcfg
.
element_ttl
,
mpath
->
dst
,
cpu_to_le32
(
mpath
->
sn
),
reason
,
bcast
,
sdata
);
mesh_path_error_tx
(
sdata
,
sdata
->
u
.
mesh
.
mshcfg
.
element_ttl
,
mpath
->
dst
,
cpu_to_le32
(
mpath
->
sn
),
reason
,
bcast
);
}
}
rcu_read_unlock
();
...
...
@@ -856,7 +859,7 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
*
* Returns: 0 if successful
*/
int
mesh_path_del
(
u8
*
addr
,
struct
ieee80211_sub_if_data
*
sdata
)
int
mesh_path_del
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
addr
)
{
struct
mesh_table
*
tbl
;
struct
mesh_path
*
mpath
;
...
...
@@ -965,8 +968,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
*
* Locking: the function must me called within a rcu_read_lock region
*/
void
mesh_path_discard_frame
(
struct
sk_buff
*
skb
,
struct
ieee80211_sub_if_data
*
sdata
)
void
mesh_path_discard_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
)
{
kfree_skb
(
skb
);
sdata
->
u
.
mesh
.
mshstats
.
dropped_frames_no_route
++
;
...
...
@@ -984,7 +987,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
struct
sk_buff
*
skb
;
while
((
skb
=
skb_dequeue
(
&
mpath
->
frame_queue
))
!=
NULL
)
mesh_path_discard_frame
(
skb
,
mpath
->
sdata
);
mesh_path_discard_frame
(
mpath
->
sdata
,
skb
);
}
/**
...
...
@@ -1105,7 +1108,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
if
((
!
(
mpath
->
flags
&
MESH_PATH_RESOLVING
))
&&
(
!
(
mpath
->
flags
&
MESH_PATH_FIXED
))
&&
time_after
(
jiffies
,
mpath
->
exp_time
+
MESH_PATH_EXPIRE
))
mesh_path_del
(
mpath
->
dst
,
mpath
->
sdata
);
mesh_path_del
(
mpath
->
sdata
,
mpath
->
dst
);
}
rcu_read_unlock
();
}
...
...
net/mac80211/mesh_plink.c
浏览文件 @
a9908ebf
...
...
@@ -37,9 +37,31 @@ enum plink_event {
CLS_IGNR
};
static
const
char
*
const
mplstates
[]
=
{
[
NL80211_PLINK_LISTEN
]
=
"LISTEN"
,
[
NL80211_PLINK_OPN_SNT
]
=
"OPN-SNT"
,
[
NL80211_PLINK_OPN_RCVD
]
=
"OPN-RCVD"
,
[
NL80211_PLINK_CNF_RCVD
]
=
"CNF_RCVD"
,
[
NL80211_PLINK_ESTAB
]
=
"ESTAB"
,
[
NL80211_PLINK_HOLDING
]
=
"HOLDING"
,
[
NL80211_PLINK_BLOCKED
]
=
"BLOCKED"
};
static
const
char
*
const
mplevents
[]
=
{
[
PLINK_UNDEFINED
]
=
"NONE"
,
[
OPN_ACPT
]
=
"OPN_ACPT"
,
[
OPN_RJCT
]
=
"OPN_RJCT"
,
[
OPN_IGNR
]
=
"OPN_IGNR"
,
[
CNF_ACPT
]
=
"CNF_ACPT"
,
[
CNF_RJCT
]
=
"CNF_RJCT"
,
[
CNF_IGNR
]
=
"CNF_IGNR"
,
[
CLS_ACPT
]
=
"CLS_ACPT"
,
[
CLS_IGNR
]
=
"CLS_IGNR"
};
static
int
mesh_plink_frame_tx
(
struct
ieee80211_sub_if_data
*
sdata
,
enum
ieee80211_self_protected_actioncode
action
,
u8
*
da
,
__le16
llid
,
__le16
plid
,
__le16
reason
);
enum
ieee80211_self_protected_actioncode
action
,
u8
*
da
,
__le16
llid
,
__le16
plid
,
__le16
reason
);
/**
* mesh_plink_fsm_restart - restart a mesh peer link finite state machine
...
...
@@ -129,7 +151,6 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sta_info
*
sta
;
u32
changed
=
0
;
u16
ht_opmode
;
bool
non_ht_sta
=
false
,
ht20_sta
=
false
;
...
...
@@ -142,23 +163,19 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
sta
->
plink_state
!=
NL80211_PLINK_ESTAB
)
continue
;
switch
(
sta
->
ch_width
)
{
case
NL80211_CHAN_WIDTH_20_NOHT
:
mpl_dbg
(
sdata
,
"mesh_plink %pM: nonHT sta (%pM) is present
\n
"
,
sdata
->
vif
.
addr
,
sta
->
sta
.
addr
);
if
(
sta
->
sta
.
bandwidth
>
IEEE80211_STA_RX_BW_20
)
continue
;
if
(
!
sta
->
sta
.
ht_cap
.
ht_supported
)
{
mpl_dbg
(
sdata
,
"nonHT sta (%pM) is present
\n
"
,
sta
->
sta
.
addr
);
non_ht_sta
=
true
;
goto
out
;
case
NL80211_CHAN_WIDTH_20
:
mpl_dbg
(
sdata
,
"mesh_plink %pM: HT20 sta (%pM) is present
\n
"
,
sdata
->
vif
.
addr
,
sta
->
sta
.
addr
);
ht20_sta
=
true
;
default:
break
;
}
mpl_dbg
(
sdata
,
"HT20 sta (%pM) is present
\n
"
,
sta
->
sta
.
addr
);
ht20_sta
=
true
;
}
out:
rcu_read_unlock
();
if
(
non_ht_sta
)
...
...
@@ -169,16 +186,13 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
else
ht_opmode
=
IEEE80211_HT_OP_MODE_PROTECTION_NONE
;
if
(
sdata
->
vif
.
bss_conf
.
ht_operation_mode
!=
ht_opmode
)
{
sdata
->
vif
.
bss_conf
.
ht_operation_mode
=
ht_opmode
;
sdata
->
u
.
mesh
.
mshcfg
.
ht_opmode
=
ht_opmode
;
changed
=
BSS_CHANGED_HT
;
mpl_dbg
(
sdata
,
"mesh_plink %pM: protection mode changed to %d
\n
"
,
sdata
->
vif
.
addr
,
ht_opmode
);
}
if
(
sdata
->
vif
.
bss_conf
.
ht_operation_mode
==
ht_opmode
)
return
0
;
return
changed
;
sdata
->
vif
.
bss_conf
.
ht_operation_mode
=
ht_opmode
;
sdata
->
u
.
mesh
.
mshcfg
.
ht_opmode
=
ht_opmode
;
mpl_dbg
(
sdata
,
"selected new HT protection mode %d
\n
"
,
ht_opmode
);
return
BSS_CHANGED_HT
;
}
/**
...
...
@@ -231,8 +245,9 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
}
static
int
mesh_plink_frame_tx
(
struct
ieee80211_sub_if_data
*
sdata
,
enum
ieee80211_self_protected_actioncode
action
,
u8
*
da
,
__le16
llid
,
__le16
plid
,
__le16
reason
)
{
enum
ieee80211_self_protected_actioncode
action
,
u8
*
da
,
__le16
llid
,
__le16
plid
,
__le16
reason
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sk_buff
*
skb
;
struct
ieee80211_tx_info
*
info
;
...
...
@@ -283,13 +298,13 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
}
if
(
ieee80211_add_srates_ie
(
sdata
,
skb
,
true
,
band
)
||
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
true
,
band
)
||
mesh_add_rsn_ie
(
s
kb
,
sdata
)
||
mesh_add_meshid_ie
(
s
kb
,
sdata
)
||
mesh_add_meshconf_ie
(
s
kb
,
sdata
))
mesh_add_rsn_ie
(
s
data
,
skb
)
||
mesh_add_meshid_ie
(
s
data
,
skb
)
||
mesh_add_meshconf_ie
(
s
data
,
skb
))
goto
free
;
}
else
{
/* WLAN_SP_MESH_PEERING_CLOSE */
info
->
flags
|=
IEEE80211_TX_CTL_NO_ACK
;
if
(
mesh_add_meshid_ie
(
s
kb
,
sdata
))
if
(
mesh_add_meshid_ie
(
s
data
,
skb
))
goto
free
;
}
...
...
@@ -333,12 +348,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
}
if
(
action
!=
WLAN_SP_MESH_PEERING_CLOSE
)
{
if
(
mesh_add_ht_cap_ie
(
s
kb
,
sdata
)
||
mesh_add_ht_oper_ie
(
s
kb
,
sdata
))
if
(
mesh_add_ht_cap_ie
(
s
data
,
skb
)
||
mesh_add_ht_oper_ie
(
s
data
,
skb
))
goto
free
;
}
if
(
mesh_add_vendor_ies
(
s
kb
,
sdata
))
if
(
mesh_add_vendor_ies
(
s
data
,
skb
))
goto
free
;
ieee80211_tx_skb
(
sdata
,
skb
);
...
...
@@ -370,24 +385,18 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
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
)
ieee80211_ht_cap_ie_to_sta_ht_cap
(
sdata
,
sband
,
elems
->
ht_cap_elem
,
sta
);
else
memset
(
&
sta
->
sta
.
ht_cap
,
0
,
sizeof
(
sta
->
sta
.
ht_cap
));
if
(
elems
->
ht_operation
)
{
struct
cfg80211_chan_def
chandef
;
if
(
ieee80211_ht_cap_ie_to_sta_ht_cap
(
sdata
,
sband
,
elems
->
ht_cap_elem
,
sta
))
changed
|=
IEEE80211_RC_BW_CHANGED
;
if
(
!
(
elems
->
ht_operation
->
ht_param
&
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY
))
sta
->
sta
.
bandwidth
=
IEEE80211_STA_RX_BW_20
;
ieee80211_ht_oper_to_chandef
(
sdata
->
vif
.
bss_conf
.
chandef
.
chan
,
elems
->
ht_operation
,
&
chandef
);
if
(
sta
->
ch_width
!=
chandef
.
width
)
/* HT peer is operating 20MHz-only */
if
(
elems
->
ht_operation
&&
!
(
elems
->
ht_operation
->
ht_param
&
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY
))
{
if
(
sta
->
sta
.
bandwidth
!=
IEEE80211_STA_RX_BW_20
)
changed
|=
IEEE80211_RC_BW_CHANGED
;
sta
->
ch_width
=
chandef
.
width
;
sta
->
sta
.
bandwidth
=
IEEE80211_STA_RX_BW_20
;
}
if
(
insert
)
...
...
@@ -666,8 +675,9 @@ u32 mesh_plink_block(struct sta_info *sta)
}
void
mesh_rx_plink_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
,
struct
ieee80211_rx_status
*
rx_status
)
void
mesh_rx_plink_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
,
struct
ieee80211_rx_status
*
rx_status
)
{
struct
mesh_config
*
mshcfg
=
&
sdata
->
u
.
mesh
.
mshcfg
;
struct
ieee802_11_elems
elems
;
...
...
@@ -680,15 +690,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
u8
*
baseaddr
;
u32
changed
=
0
;
__le16
plid
,
llid
,
reason
;
static
const
char
*
mplstates
[]
=
{
[
NL80211_PLINK_LISTEN
]
=
"LISTEN"
,
[
NL80211_PLINK_OPN_SNT
]
=
"OPN-SNT"
,
[
NL80211_PLINK_OPN_RCVD
]
=
"OPN-RCVD"
,
[
NL80211_PLINK_CNF_RCVD
]
=
"CNF_RCVD"
,
[
NL80211_PLINK_ESTAB
]
=
"ESTAB"
,
[
NL80211_PLINK_HOLDING
]
=
"HOLDING"
,
[
NL80211_PLINK_BLOCKED
]
=
"BLOCKED"
};
/* need action_code, aux */
if
(
len
<
IEEE80211_MIN_ACTION_SIZE
+
3
)
...
...
@@ -708,13 +709,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
baselen
+=
4
;
}
ieee802_11_parse_elems
(
baseaddr
,
len
-
baselen
,
&
elems
);
if
(
!
elems
.
peering
)
{
mpl_dbg
(
sdata
,
"Mesh plink: missing necessary peer link ie
\n
"
);
return
;
}
if
(
elems
.
rsn_len
&&
sdata
->
u
.
mesh
.
security
==
IEEE80211_MESH_SEC_NONE
)
{
sdata
->
u
.
mesh
.
security
==
IEEE80211_MESH_SEC_NONE
)
{
mpl_dbg
(
sdata
,
"Mesh plink: can't establish link with secure peer
\n
"
);
return
;
...
...
@@ -733,7 +736,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
if
(
ftype
!=
WLAN_SP_MESH_PEERING_CLOSE
&&
(
!
elems
.
mesh_id
||
!
elems
.
mesh_config
))
{
(
!
elems
.
mesh_id
||
!
elems
.
mesh_config
))
{
mpl_dbg
(
sdata
,
"Mesh plink: missing necessary ie
\n
"
);
return
;
}
...
...
@@ -859,11 +862,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
}
mpl_dbg
(
sdata
,
"Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d
\n
"
,
mgmt
->
sa
,
mplstates
[
sta
->
plink_state
],
le16_to_cpu
(
sta
->
llid
),
le16_to_cpu
(
sta
->
plid
),
event
);
mpl_dbg
(
sdata
,
"peer %pM in state %s got event %s
\n
"
,
mgmt
->
sa
,
mplstates
[
sta
->
plink_state
],
mplevents
[
event
]);
reason
=
0
;
spin_lock_bh
(
&
sta
->
lock
);
switch
(
sta
->
plink_state
)
{
...
...
net/mac80211/mesh_sync.c
浏览文件 @
a9908ebf
...
...
@@ -43,7 +43,7 @@ struct sync_method {
static
bool
mesh_peer_tbtt_adjusting
(
struct
ieee802_11_elems
*
ie
)
{
return
(
ie
->
mesh_config
->
meshconf_cap
&
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING
)
!=
0
;
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING
)
!=
0
;
}
void
mesh_sync_adjust_tbtt
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -112,7 +112,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if
(
elems
->
mesh_config
&&
mesh_peer_tbtt_adjusting
(
elems
))
{
clear_sta_flag
(
sta
,
WLAN_STA_TOFFSET_KNOWN
);
msync_dbg
(
sdata
,
"STA %pM : is adjusting TBTT
\n
"
,
sta
->
sta
.
addr
);
msync_dbg
(
sdata
,
"STA %pM : is adjusting TBTT
\n
"
,
sta
->
sta
.
addr
);
goto
no_sync
;
}
...
...
@@ -129,18 +130,15 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
sta
->
t_offset
=
t_t
-
t_r
;
if
(
test_sta_flag
(
sta
,
WLAN_STA_TOFFSET_KNOWN
))
{
s64
t_clockdrift
=
sta
->
t_offset_setpoint
-
sta
->
t_offset
;
s64
t_clockdrift
=
sta
->
t_offset_setpoint
-
sta
->
t_offset
;
msync_dbg
(
sdata
,
"STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld
\n
"
,
sta
->
sta
.
addr
,
(
long
long
)
sta
->
t_offset
,
(
long
long
)
sta
->
t_offset_setpoint
,
sta
->
sta
.
addr
,
(
long
long
)
sta
->
t_offset
,
(
long
long
)
sta
->
t_offset_setpoint
,
(
long
long
)
t_clockdrift
);
if
(
t_clockdrift
>
TOFFSET_MAXIMUM_ADJUSTMENT
||
t_clockdrift
<
-
TOFFSET_MAXIMUM_ADJUSTMENT
)
{
t_clockdrift
<
-
TOFFSET_MAXIMUM_ADJUSTMENT
)
{
msync_dbg
(
sdata
,
"STA %pM : t_clockdrift=%lld too large, setpoint reset
\n
"
,
sta
->
sta
.
addr
,
...
...
@@ -149,15 +147,10 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
goto
no_sync
;
}
rcu_read_unlock
();
spin_lock_bh
(
&
ifmsh
->
sync_offset_lock
);
if
(
t_clockdrift
>
ifmsh
->
sync_offset_clockdrift_max
)
ifmsh
->
sync_offset_clockdrift_max
=
t_clockdrift
;
if
(
t_clockdrift
>
ifmsh
->
sync_offset_clockdrift_max
)
ifmsh
->
sync_offset_clockdrift_max
=
t_clockdrift
;
spin_unlock_bh
(
&
ifmsh
->
sync_offset_lock
);
}
else
{
sta
->
t_offset_setpoint
=
sta
->
t_offset
-
TOFFSET_SET_MARGIN
;
set_sta_flag
(
sta
,
WLAN_STA_TOFFSET_KNOWN
);
...
...
@@ -165,9 +158,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
"STA %pM : offset was invalid, sta->t_offset=%lld
\n
"
,
sta
->
sta
.
addr
,
(
long
long
)
sta
->
t_offset
);
rcu_read_unlock
();
}
return
;
no_sync:
rcu_read_unlock
();
...
...
@@ -177,14 +168,12 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
WARN_ON
(
ifmsh
->
mesh_sp_id
!=
IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET
);
WARN_ON
(
ifmsh
->
mesh_sp_id
!=
IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET
);
BUG_ON
(
!
rcu_read_lock_held
());
spin_lock_bh
(
&
ifmsh
->
sync_offset_lock
);
if
(
ifmsh
->
sync_offset_clockdrift_max
>
TOFFSET_MINIMUM_ADJUSTMENT
)
{
if
(
ifmsh
->
sync_offset_clockdrift_max
>
TOFFSET_MINIMUM_ADJUSTMENT
)
{
/* Since ajusting the tsf here would
* require a possibly blocking call
* to the driver tsf setter, we punt
...
...
@@ -193,8 +182,7 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
msync_dbg
(
sdata
,
"TBTT : kicking off TBTT adjustment with clockdrift_max=%lld
\n
"
,
ifmsh
->
sync_offset_clockdrift_max
);
set_bit
(
MESH_WORK_DRIFT_ADJUST
,
&
ifmsh
->
wrkq_flags
);
set_bit
(
MESH_WORK_DRIFT_ADJUST
,
&
ifmsh
->
wrkq_flags
);
ifmsh
->
adjusting_tbtt
=
true
;
}
else
{
...
...
@@ -220,14 +208,11 @@ static const struct sync_method sync_methods[] = {
const
struct
ieee80211_mesh_sync_ops
*
ieee80211_mesh_sync_ops_get
(
u8
method
)
{
const
struct
ieee80211_mesh_sync_ops
*
ops
=
NULL
;
u8
i
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sync_methods
);
++
i
)
{
if
(
sync_methods
[
i
].
method
==
method
)
{
ops
=
&
sync_methods
[
i
].
ops
;
break
;
}
if
(
sync_methods
[
i
].
method
==
method
)
return
&
sync_methods
[
i
].
ops
;
}
return
ops
;
return
NULL
;
}
net/mac80211/rx.c
浏览文件 @
a9908ebf
...
...
@@ -2027,7 +2027,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
/* frame is in RMC, don't forward */
if
(
ieee80211_is_data
(
hdr
->
frame_control
)
&&
is_multicast_ether_addr
(
hdr
->
addr1
)
&&
mesh_rmc_check
(
hdr
->
addr3
,
mesh_hdr
,
rx
->
sdata
))
mesh_rmc_check
(
rx
->
sdata
,
hdr
->
addr3
,
mesh_hdr
))
return
RX_DROP_MONITOR
;
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
||
...
...
@@ -2054,9 +2054,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
rcu_read_lock
();
mppath
=
mpp_path_lookup
(
proxied_addr
,
sdata
);
mppath
=
mpp_path_lookup
(
sdata
,
proxied_addr
);
if
(
!
mppath
)
{
mpp_path_add
(
proxied_addr
,
mpp_addr
,
sdata
);
mpp_path_add
(
sdata
,
proxied_addr
,
mpp_addr
);
}
else
{
spin_lock_bh
(
&
mppath
->
state_lock
);
if
(
!
ether_addr_equal
(
mppath
->
mpp
,
mpp_addr
))
...
...
@@ -2104,13 +2104,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
memcpy
(
fwd_hdr
->
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
/* update power mode indication when forwarding */
ieee80211_mps_set_frame_flags
(
sdata
,
NULL
,
fwd_hdr
);
}
else
if
(
!
mesh_nexthop_lookup
(
fwd_skb
,
sdata
))
{
}
else
if
(
!
mesh_nexthop_lookup
(
sdata
,
fwd_skb
))
{
/* mesh power mode flags updated in mesh_nexthop_lookup */
IEEE80211_IFSTA_MESH_CTR_INC
(
ifmsh
,
fwded_unicast
);
}
else
{
/* unable to resolve next hop */
mesh_path_error_tx
(
ifmsh
->
mshcfg
.
element_ttl
,
fwd_hdr
->
addr3
,
0
,
reason
,
fwd_hdr
->
addr2
,
sdata
);
mesh_path_error_tx
(
sdata
,
ifmsh
->
mshcfg
.
element_ttl
,
fwd_hdr
->
addr3
,
0
,
reason
,
fwd_hdr
->
addr2
);
IEEE80211_IFSTA_MESH_CTR_INC
(
ifmsh
,
dropped_frames_no_route
);
kfree_skb
(
fwd_skb
);
return
RX_DROP_MONITOR
;
...
...
net/mac80211/sta_info.h
浏览文件 @
a9908ebf
...
...
@@ -285,7 +285,6 @@ struct sta_ampdu_mlme {
* @t_offset: timing offset relative to this host
* @t_offset_setpoint: reference timing offset of this sta to be used when
* calculating clockdrift
* @ch_width: peer's channel width
* @local_pm: local link-specific power save mode
* @peer_pm: peer-specific power save mode towards local STA
* @nonpeer_pm: STA power save mode towards non-peer neighbors
...
...
@@ -386,7 +385,6 @@ struct sta_info {
struct
timer_list
plink_timer
;
s64
t_offset
;
s64
t_offset_setpoint
;
enum
nl80211_chan_width
ch_width
;
/* mesh power save */
enum
nl80211_mesh_power_mode
local_pm
;
enum
nl80211_mesh_power_mode
peer_pm
;
...
...
net/mac80211/trace.h
浏览文件 @
a9908ebf
...
...
@@ -479,7 +479,7 @@ TRACE_EVENT(drv_set_tim,
TP_printk
(
LOCAL_PR_FMT
STA_PR_FMT
" set:%d"
,
LOCAL_PR_ARG
,
STA_PR_
FMT
,
__entry
->
set
LOCAL_PR_ARG
,
STA_PR_
ARG
,
__entry
->
set
)
);
...
...
@@ -1684,7 +1684,7 @@ TRACE_EVENT(api_sta_block_awake,
TP_printk
(
LOCAL_PR_FMT
STA_PR_FMT
" block:%d"
,
LOCAL_PR_ARG
,
STA_PR_
FMT
,
__entry
->
block
LOCAL_PR_ARG
,
STA_PR_
ARG
,
__entry
->
block
)
);
...
...
@@ -1782,7 +1782,7 @@ TRACE_EVENT(api_eosp,
TP_printk
(
LOCAL_PR_FMT
STA_PR_FMT
,
LOCAL_PR_ARG
,
STA_PR_
FMT
LOCAL_PR_ARG
,
STA_PR_
ARG
)
);
...
...
net/mac80211/tx.c
浏览文件 @
a9908ebf
...
...
@@ -1495,7 +1495,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
if
(
ieee80211_vif_is_mesh
(
&
sdata
->
vif
))
{
if
(
ieee80211_is_data
(
hdr
->
frame_control
)
&&
is_unicast_ether_addr
(
hdr
->
addr1
))
{
if
(
mesh_nexthop_resolve
(
s
kb
,
sdata
))
if
(
mesh_nexthop_resolve
(
s
data
,
skb
))
return
;
/* skb queued: don't free */
}
else
{
ieee80211_mps_set_frame_flags
(
sdata
,
NULL
,
hdr
);
...
...
@@ -1844,9 +1844,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
}
if
(
!
is_multicast_ether_addr
(
skb
->
data
))
{
mpath
=
mesh_path_lookup
(
s
kb
->
data
,
s
data
);
mpath
=
mesh_path_lookup
(
s
data
,
skb
->
data
);
if
(
!
mpath
)
mppath
=
mpp_path_lookup
(
s
kb
->
data
,
s
data
);
mppath
=
mpp_path_lookup
(
s
data
,
skb
->
data
);
}
/*
...
...
@@ -1859,8 +1859,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
!
(
mppath
&&
!
ether_addr_equal
(
mppath
->
mpp
,
skb
->
data
)))
{
hdrlen
=
ieee80211_fill_mesh_addresses
(
&
hdr
,
&
fc
,
skb
->
data
,
skb
->
data
+
ETH_ALEN
);
meshhdrlen
=
ieee80211_new_mesh_header
(
&
mesh_hdr
,
sdata
,
NULL
,
NULL
);
meshhdrlen
=
ieee80211_new_mesh_header
(
sdata
,
&
mesh_hdr
,
NULL
,
NULL
);
}
else
{
/* DS -> MBSS (802.11-2012 13.11.3.3).
* For unicast with unknown forwarding information,
...
...
@@ -1879,18 +1879,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
mesh_da
,
sdata
->
vif
.
addr
);
if
(
is_multicast_ether_addr
(
mesh_da
))
/* DA TA mSA AE:SA */
meshhdrlen
=
ieee80211_new_mesh_header
(
&
mesh_hdr
,
sdata
,
skb
->
data
+
ETH_ALEN
,
NULL
);
meshhdrlen
=
ieee80211_new_mesh_header
(
sdata
,
&
mesh_hdr
,
skb
->
data
+
ETH_ALEN
,
NULL
);
else
/* RA TA mDA mSA AE:DA SA */
meshhdrlen
=
ieee80211_new_mesh_header
(
&
mesh_hdr
,
sdata
,
skb
->
data
,
skb
->
data
+
ETH_ALEN
);
meshhdrlen
=
ieee80211_new_mesh_header
(
sdata
,
&
mesh_hdr
,
skb
->
data
,
skb
->
data
+
ETH_ALEN
);
}
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
...
...
net/wireless/nl80211.c
浏览文件 @
a9908ebf
...
...
@@ -3418,19 +3418,10 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
static
int
nl80211_set_station_tdls
(
struct
genl_info
*
info
,
struct
station_parameters
*
params
)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
nlattr
*
tb
[
NL80211_STA_WME_MAX
+
1
];
struct
nlattr
*
nla
;
int
err
;
/* Can only set if TDLS ... */
if
(
!
(
rdev
->
wiphy
.
flags
&
WIPHY_FLAG_SUPPORTS_TDLS
))
return
-
EOPNOTSUPP
;
/* ... with external setup is supported */
if
(
!
(
rdev
->
wiphy
.
flags
&
WIPHY_FLAG_TDLS_EXTERNAL_SETUP
))
return
-
EOPNOTSUPP
;
/* Dummy STA entry gets updated once the peer capabilities are known */
if
(
info
->
attrs
[
NL80211_ATTR_HT_CAPABILITY
])
params
->
ht_capa
=
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录