Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
16b1aba8
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
16b1aba8
编写于
1月 19, 2011
作者:
M
Marek Lindner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
batman-adv: protect originator nodes with reference counters
Signed-off-by:
N
Marek Lindner
<
lindner_marek@yahoo.de
>
上级
fb778ea1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
78 addition
and
19 deletion
+78
-19
net/batman-adv/originator.c
net/batman-adv/originator.c
+52
-9
net/batman-adv/originator.h
net/batman-adv/originator.h
+1
-0
net/batman-adv/routing.c
net/batman-adv/routing.c
+23
-10
net/batman-adv/types.h
net/batman-adv/types.h
+2
-0
未找到文件。
net/batman-adv/originator.c
浏览文件 @
16b1aba8
...
...
@@ -103,12 +103,13 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
return
neigh_node
;
}
static
void
free_orig_node
(
void
*
data
,
void
*
arg
)
void
orig_node_free_ref
(
struct
kref
*
refcount
)
{
struct
hlist_node
*
node
,
*
node_tmp
;
struct
neigh_node
*
neigh_node
;
struct
orig_node
*
orig_node
=
(
struct
orig_node
*
)
data
;
struct
bat_priv
*
bat_priv
=
(
struct
bat_priv
*
)
arg
;
struct
orig_node
*
orig_node
;
orig_node
=
container_of
(
refcount
,
struct
orig_node
,
refcount
);
spin_lock_bh
(
&
orig_node
->
neigh_list_lock
);
...
...
@@ -122,7 +123,8 @@ static void free_orig_node(void *data, void *arg)
spin_unlock_bh
(
&
orig_node
->
neigh_list_lock
);
frag_list_free
(
&
orig_node
->
frag_list
);
hna_global_del_orig
(
bat_priv
,
orig_node
,
"originator timed out"
);
hna_global_del_orig
(
orig_node
->
bat_priv
,
orig_node
,
"originator timed out"
);
kfree
(
orig_node
->
bcast_own
);
kfree
(
orig_node
->
bcast_own_sum
);
...
...
@@ -131,17 +133,53 @@ static void free_orig_node(void *data, void *arg)
void
originator_free
(
struct
bat_priv
*
bat_priv
)
{
if
(
!
bat_priv
->
orig_hash
)
struct
hashtable_t
*
hash
=
bat_priv
->
orig_hash
;
struct
hlist_node
*
walk
,
*
safe
;
struct
hlist_head
*
head
;
struct
element_t
*
bucket
;
spinlock_t
*
list_lock
;
/* spinlock to protect write access */
struct
orig_node
*
orig_node
;
int
i
;
if
(
!
hash
)
return
;
cancel_delayed_work_sync
(
&
bat_priv
->
orig_work
);
spin_lock_bh
(
&
bat_priv
->
orig_hash_lock
);
hash_delete
(
bat_priv
->
orig_hash
,
free_orig_node
,
bat_priv
);
bat_priv
->
orig_hash
=
NULL
;
for
(
i
=
0
;
i
<
hash
->
size
;
i
++
)
{
head
=
&
hash
->
table
[
i
];
list_lock
=
&
hash
->
list_locks
[
i
];
spin_lock_bh
(
list_lock
);
hlist_for_each_entry_safe
(
bucket
,
walk
,
safe
,
head
,
hlist
)
{
orig_node
=
bucket
->
data
;
hlist_del_rcu
(
walk
);
call_rcu
(
&
bucket
->
rcu
,
bucket_free_rcu
);
kref_put
(
&
orig_node
->
refcount
,
orig_node_free_ref
);
}
spin_unlock_bh
(
list_lock
);
}
hash_destroy
(
hash
);
spin_unlock_bh
(
&
bat_priv
->
orig_hash_lock
);
}
static
void
bucket_free_orig_rcu
(
struct
rcu_head
*
rcu
)
{
struct
element_t
*
bucket
;
struct
orig_node
*
orig_node
;
bucket
=
container_of
(
rcu
,
struct
element_t
,
rcu
);
orig_node
=
bucket
->
data
;
kref_put
(
&
orig_node
->
refcount
,
orig_node_free_ref
);
kfree
(
bucket
);
}
/* this function finds or creates an originator entry for the given
* address if it does not exits */
struct
orig_node
*
get_orig_node
(
struct
bat_priv
*
bat_priv
,
uint8_t
*
addr
)
...
...
@@ -156,8 +194,10 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
addr
));
rcu_read_unlock
();
if
(
orig_node
)
if
(
orig_node
)
{
kref_get
(
&
orig_node
->
refcount
);
return
orig_node
;
}
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Creating new originator: %pM
\n
"
,
addr
);
...
...
@@ -168,7 +208,9 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
INIT_HLIST_HEAD
(
&
orig_node
->
neigh_list
);
spin_lock_init
(
&
orig_node
->
neigh_list_lock
);
kref_init
(
&
orig_node
->
refcount
);
orig_node
->
bat_priv
=
bat_priv
;
memcpy
(
orig_node
->
orig
,
addr
,
ETH_ALEN
);
orig_node
->
router
=
NULL
;
orig_node
->
hna_buff
=
NULL
;
...
...
@@ -197,6 +239,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
if
(
hash_added
<
0
)
goto
free_bcast_own_sum
;
/* extra reference for return */
kref_get
(
&
orig_node
->
refcount
);
return
orig_node
;
free_bcast_own_sum:
kfree
(
orig_node
->
bcast_own_sum
);
...
...
@@ -318,8 +362,7 @@ static void _purge_orig(struct bat_priv *bat_priv)
if
(
orig_node
->
gw_flags
)
gw_node_delete
(
bat_priv
,
orig_node
);
hlist_del_rcu
(
walk
);
call_rcu
(
&
bucket
->
rcu
,
bucket_free_rcu
);
free_orig_node
(
orig_node
,
bat_priv
);
call_rcu
(
&
bucket
->
rcu
,
bucket_free_orig_rcu
);
continue
;
}
...
...
net/batman-adv/originator.h
浏览文件 @
16b1aba8
...
...
@@ -25,6 +25,7 @@
int
originator_init
(
struct
bat_priv
*
bat_priv
);
void
originator_free
(
struct
bat_priv
*
bat_priv
);
void
purge_orig_ref
(
struct
bat_priv
*
bat_priv
);
void
orig_node_free_ref
(
struct
kref
*
refcount
);
struct
orig_node
*
get_orig_node
(
struct
bat_priv
*
bat_priv
,
uint8_t
*
addr
);
struct
neigh_node
*
create_neighbor
(
struct
orig_node
*
orig_node
,
struct
orig_node
*
orig_neigh_node
,
...
...
net/batman-adv/routing.c
浏览文件 @
16b1aba8
...
...
@@ -311,6 +311,8 @@ static void update_orig(struct bat_priv *bat_priv,
neigh_node
=
create_neighbor
(
orig_node
,
orig_tmp
,
ethhdr
->
h_source
,
if_incoming
);
kref_put
(
&
orig_tmp
->
refcount
,
orig_node_free_ref
);
if
(
!
neigh_node
)
goto
unlock
;
}
else
...
...
@@ -438,7 +440,7 @@ static char count_real_packets(struct ethhdr *ethhdr,
/* signalize caller that the packet is to be dropped. */
if
(
window_protected
(
bat_priv
,
seq_diff
,
&
orig_node
->
batman_seqno_reset
))
return
-
1
;
goto
err
;
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
...
...
@@ -471,7 +473,12 @@ static char count_real_packets(struct ethhdr *ethhdr,
orig_node
->
last_real_seqno
=
batman_packet
->
seqno
;
}
kref_put
(
&
orig_node
->
refcount
,
orig_node_free_ref
);
return
is_duplicate
;
err:
kref_put
(
&
orig_node
->
refcount
,
orig_node_free_ref
);
return
-
1
;
}
/* copy primary address for bonding */
...
...
@@ -686,7 +693,6 @@ void receive_bat_packet(struct ethhdr *ethhdr,
int
offset
;
orig_neigh_node
=
get_orig_node
(
bat_priv
,
ethhdr
->
h_source
);
if
(
!
orig_neigh_node
)
return
;
...
...
@@ -707,6 +713,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: "
"originator packet from myself (via neighbor)
\n
"
);
kref_put
(
&
orig_neigh_node
->
refcount
,
orig_node_free_ref
);
return
;
}
...
...
@@ -727,13 +734,13 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: packet within seqno protection time "
"(sender: %pM)
\n
"
,
ethhdr
->
h_source
);
return
;
goto
out
;
}
if
(
batman_packet
->
tq
==
0
)
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: originator packet with tq equal 0
\n
"
);
return
;
goto
out
;
}
/* avoid temporary routing loops */
...
...
@@ -747,7 +754,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: ignoring all rebroadcast packets that "
"may make me loop (sender: %pM)
\n
"
,
ethhdr
->
h_source
);
return
;
goto
out
;
}
/* if sender is a direct neighbor the sender mac equals
...
...
@@ -756,14 +763,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
orig_node
:
get_orig_node
(
bat_priv
,
ethhdr
->
h_source
));
if
(
!
orig_neigh_node
)
return
;
goto
out_neigh
;
/* drop packet if sender is not a direct neighbor and if we
* don't route towards it */
if
(
!
is_single_hop_neigh
&&
(
!
orig_neigh_node
->
router
))
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: OGM via unknown neighbor!
\n
"
);
return
;
goto
out_neigh
;
}
is_bidirectional
=
is_bidirectional_neigh
(
orig_node
,
orig_neigh_node
,
...
...
@@ -790,26 +797,32 @@ void receive_bat_packet(struct ethhdr *ethhdr,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Forwarding packet: "
"rebroadcast neighbor packet with direct link flag
\n
"
);
return
;
goto
out_neigh
;
}
/* multihop originator */
if
(
!
is_bidirectional
)
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: not received via bidirectional link
\n
"
);
return
;
goto
out_neigh
;
}
if
(
is_duplicate
)
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Drop packet: duplicate packet received
\n
"
);
return
;
goto
out_neigh
;
}
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Forwarding packet: rebroadcast originator packet
\n
"
);
schedule_forward_packet
(
orig_node
,
ethhdr
,
batman_packet
,
0
,
hna_buff_len
,
if_incoming
);
out_neigh:
if
(
!
is_single_hop_neigh
)
kref_put
(
&
orig_neigh_node
->
refcount
,
orig_node_free_ref
);
out:
kref_put
(
&
orig_node
->
refcount
,
orig_node_free_ref
);
}
int
recv_bat_packet
(
struct
sk_buff
*
skb
,
struct
batman_if
*
batman_if
)
...
...
net/batman-adv/types.h
浏览文件 @
16b1aba8
...
...
@@ -86,6 +86,8 @@ struct orig_node {
struct
hlist_head
neigh_list
;
struct
list_head
frag_list
;
spinlock_t
neigh_list_lock
;
/* protects neighbor list */
struct
kref
refcount
;
struct
bat_priv
*
bat_priv
;
unsigned
long
last_frag_packet
;
struct
{
uint8_t
candidates
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录