Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
3f9aed7c
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
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看板
提交
3f9aed7c
编写于
7月 08, 2011
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'batman-adv/next' of
git://git.open-mesh.org/linux-merge
上级
31817df0
a7f9becb
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
147 addition
and
32 deletion
+147
-32
net/batman-adv/originator.c
net/batman-adv/originator.c
+2
-0
net/batman-adv/packet.h
net/batman-adv/packet.h
+3
-1
net/batman-adv/routing.c
net/batman-adv/routing.c
+12
-0
net/batman-adv/send.c
net/batman-adv/send.c
+1
-3
net/batman-adv/translation-table.c
net/batman-adv/translation-table.c
+128
-28
net/batman-adv/translation-table.h
net/batman-adv/translation-table.h
+1
-0
未找到文件。
net/batman-adv/originator.c
浏览文件 @
3f9aed7c
...
...
@@ -223,6 +223,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
orig_node
->
bat_priv
=
bat_priv
;
memcpy
(
orig_node
->
orig
,
addr
,
ETH_ALEN
);
orig_node
->
router
=
NULL
;
orig_node
->
tt_crc
=
0
;
atomic_set
(
&
orig_node
->
last_ttvn
,
0
);
orig_node
->
tt_buff
=
NULL
;
orig_node
->
tt_buff_len
=
0
;
atomic_set
(
&
orig_node
->
tt_size
,
0
);
...
...
net/batman-adv/packet.h
浏览文件 @
3f9aed7c
...
...
@@ -84,7 +84,9 @@ enum tt_query_flags {
enum
tt_client_flags
{
TT_CLIENT_DEL
=
1
<<
0
,
TT_CLIENT_ROAM
=
1
<<
1
,
TT_CLIENT_NOPURGE
=
1
<<
8
TT_CLIENT_NOPURGE
=
1
<<
8
,
TT_CLIENT_NEW
=
1
<<
9
,
TT_CLIENT_PENDING
=
1
<<
10
};
struct
batman_packet
{
...
...
net/batman-adv/routing.c
浏览文件 @
3f9aed7c
...
...
@@ -91,6 +91,18 @@ static void update_transtable(struct bat_priv *bat_priv,
* to recompute it to spot any possible inconsistency
* in the global table */
orig_node
->
tt_crc
=
tt_global_crc
(
bat_priv
,
orig_node
);
/* The ttvn alone is not enough to guarantee consistency
* because a single value could repesent different states
* (due to the wrap around). Thus a node has to check whether
* the resulting table (after applying the changes) is still
* consistent or not. E.g. a node could disconnect while its
* ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
* checking the CRC value is mandatory to detect the
* inconsistency */
if
(
orig_node
->
tt_crc
!=
tt_crc
)
goto
request_table
;
/* Roaming phase is over: tables are in sync again. I can
* unset the flag */
orig_node
->
tt_poss_change
=
false
;
...
...
net/batman-adv/send.c
浏览文件 @
3f9aed7c
...
...
@@ -309,10 +309,8 @@ void schedule_own_packet(struct hard_iface *hard_iface)
if
(
hard_iface
==
primary_if
)
{
/* if at least one change happened */
if
(
atomic_read
(
&
bat_priv
->
tt_local_changes
)
>
0
)
{
tt_commit_changes
(
bat_priv
);
prepare_packet_buffer
(
bat_priv
,
hard_iface
);
/* Increment the TTVN only once per OGM interval */
atomic_inc
(
&
bat_priv
->
ttvn
);
bat_priv
->
tt_poss_change
=
false
;
}
/* if the changes have been sent enough times */
...
...
net/batman-adv/translation-table.c
浏览文件 @
3f9aed7c
...
...
@@ -215,11 +215,14 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr)
tt_local_event
(
bat_priv
,
addr
,
tt_local_entry
->
flags
);
/* The local entry has to be marked as NEW to avoid to send it in
* a full table response going out before the next ttvn increment
* (consistency check) */
tt_local_entry
->
flags
|=
TT_CLIENT_NEW
;
hash_add
(
bat_priv
->
tt_local_hash
,
compare_ltt
,
choose_orig
,
tt_local_entry
,
&
tt_local_entry
->
hash_entry
);
atomic_inc
(
&
bat_priv
->
num_local_tt
);
/* remove address from global hash if present */
tt_global_entry
=
tt_global_hash_find
(
bat_priv
,
addr
);
...
...
@@ -227,8 +230,9 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr)
if
(
tt_global_entry
)
{
/* This node is probably going to update its tt table */
tt_global_entry
->
orig_node
->
tt_poss_change
=
true
;
_tt_global_del
(
bat_priv
,
tt_global_entry
,
"local tt received"
);
/* The global entry has to be marked as PENDING and has to be
* kept for consistency purpose */
tt_global_entry
->
flags
|=
TT_CLIENT_PENDING
;
send_roam_adv
(
bat_priv
,
tt_global_entry
->
addr
,
tt_global_entry
->
orig_node
);
}
...
...
@@ -358,19 +362,17 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset)
return
ret
;
}
static
void
tt_local_
del
(
struct
bat_priv
*
bat_priv
,
struct
tt_local_entry
*
tt_local_entry
,
const
char
*
message
)
static
void
tt_local_
set_pending
(
struct
bat_priv
*
bat_priv
,
struct
tt_local_entry
*
tt_local_entry
,
uint16_t
flags
)
{
bat_dbg
(
DBG_TT
,
bat_priv
,
"Deleting local tt entry (%pM): %s
\n
"
,
tt_local_entry
->
addr
,
message
);
atomic_dec
(
&
bat_priv
->
num_local_tt
);
hash_remove
(
bat_priv
->
tt_local_hash
,
compare_ltt
,
choose_orig
,
tt_local_entry
->
addr
);
tt_local_event
(
bat_priv
,
tt_local_entry
->
addr
,
tt_local_entry
->
flags
|
flags
);
tt_local_entry_free_ref
(
tt_local_entry
);
/* The local client has to be merked as "pending to be removed" but has
* to be kept in the table in order to send it in an full tables
* response issued before the net ttvn increment (consistency check) */
tt_local_entry
->
flags
|=
TT_CLIENT_PENDING
;
}
void
tt_local_remove
(
struct
bat_priv
*
bat_priv
,
const
uint8_t
*
addr
,
...
...
@@ -379,14 +381,14 @@ void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
struct
tt_local_entry
*
tt_local_entry
=
NULL
;
tt_local_entry
=
tt_local_hash_find
(
bat_priv
,
addr
);
if
(
!
tt_local_entry
)
goto
out
;
tt_local_event
(
bat_priv
,
tt_local_entry
->
addr
,
tt_local_entry
->
flags
|
TT_CLIENT_DEL
|
(
roaming
?
TT_CLIENT_ROAM
:
NO_FLAGS
));
tt_local_del
(
bat_priv
,
tt_local_entry
,
message
);
tt_local_set_pending
(
bat_priv
,
tt_local_entry
,
TT_CLIENT_DEL
|
(
roaming
?
TT_CLIENT_ROAM
:
NO_FLAGS
));
bat_dbg
(
DBG_TT
,
bat_priv
,
"Local tt entry (%pM) pending to be removed: "
"%s
\n
"
,
tt_local_entry
->
addr
,
message
);
out:
if
(
tt_local_entry
)
tt_local_entry_free_ref
(
tt_local_entry
);
...
...
@@ -411,18 +413,19 @@ static void tt_local_purge(struct bat_priv *bat_priv)
if
(
tt_local_entry
->
flags
&
TT_CLIENT_NOPURGE
)
continue
;
/* entry already marked for deletion */
if
(
tt_local_entry
->
flags
&
TT_CLIENT_PENDING
)
continue
;
if
(
!
is_out_of_time
(
tt_local_entry
->
last_seen
,
TT_LOCAL_TIMEOUT
*
1000
))
continue
;
tt_local_event
(
bat_priv
,
tt_local_entry
->
addr
,
tt_local_entry
->
flags
|
TT_CLIENT_DEL
);
atomic_dec
(
&
bat_priv
->
num_local_tt
);
bat_dbg
(
DBG_TT
,
bat_priv
,
"Deleting local "
"tt entry (%pM): timed out
\n
"
,
tt_local_set_pending
(
bat_priv
,
tt_local_entry
,
TT_CLIENT_DEL
);
bat_dbg
(
DBG_TT
,
bat_priv
,
"Local tt entry (%pM) "
"pending to be removed: timed out
\n
"
,
tt_local_entry
->
addr
);
hlist_del_rcu
(
node
);
tt_local_entry_free_ref
(
tt_local_entry
);
}
spin_unlock_bh
(
list_lock
);
}
...
...
@@ -785,6 +788,11 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv,
if
(
!
atomic_inc_not_zero
(
&
tt_global_entry
->
orig_node
->
refcount
))
goto
free_tt
;
/* A global client marked as PENDING has already moved from that
* originator */
if
(
tt_global_entry
->
flags
&
TT_CLIENT_PENDING
)
goto
free_tt
;
orig_node
=
tt_global_entry
->
orig_node
;
free_tt:
...
...
@@ -846,6 +854,10 @@ uint16_t tt_local_crc(struct bat_priv *bat_priv)
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tt_local_entry
,
node
,
head
,
hash_entry
)
{
/* not yet committed clients have not to be taken into
* account while computing the CRC */
if
(
tt_local_entry
->
flags
&
TT_CLIENT_NEW
)
continue
;
total_one
=
0
;
for
(
j
=
0
;
j
<
ETH_ALEN
;
j
++
)
total_one
=
crc16_byte
(
total_one
,
...
...
@@ -935,6 +947,16 @@ static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
return
tt_req_node
;
}
/* data_ptr is useless here, but has to be kept to respect the prototype */
static
int
tt_local_valid_entry
(
const
void
*
entry_ptr
,
const
void
*
data_ptr
)
{
const
struct
tt_local_entry
*
tt_local_entry
=
entry_ptr
;
if
(
tt_local_entry
->
flags
&
TT_CLIENT_NEW
)
return
0
;
return
1
;
}
static
int
tt_global_valid_entry
(
const
void
*
entry_ptr
,
const
void
*
data_ptr
)
{
const
struct
tt_global_entry
*
tt_global_entry
=
entry_ptr
;
...
...
@@ -1275,7 +1297,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
skb
=
tt_response_fill_table
(
tt_len
,
ttvn
,
bat_priv
->
tt_local_hash
,
primary_if
,
NULL
,
NULL
);
primary_if
,
tt_local_valid_entry
,
NULL
);
if
(
!
skb
)
goto
out
;
...
...
@@ -1400,6 +1423,10 @@ bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
tt_local_entry
=
tt_local_hash_find
(
bat_priv
,
addr
);
if
(
!
tt_local_entry
)
goto
out
;
/* Check if the client has been logically deleted (but is kept for
* consistency purpose) */
if
(
tt_local_entry
->
flags
&
TT_CLIENT_PENDING
)
goto
out
;
ret
=
true
;
out:
if
(
tt_local_entry
)
...
...
@@ -1620,3 +1647,76 @@ void tt_free(struct bat_priv *bat_priv)
kfree
(
bat_priv
->
tt_buff
);
}
/* This function will reset the specified flags from all the entries in
* the given hash table and will increment num_local_tt for each involved
* entry */
static
void
tt_local_reset_flags
(
struct
bat_priv
*
bat_priv
,
uint16_t
flags
)
{
int
i
;
struct
hashtable_t
*
hash
=
bat_priv
->
tt_local_hash
;
struct
hlist_head
*
head
;
struct
hlist_node
*
node
;
struct
tt_local_entry
*
tt_local_entry
;
if
(
!
hash
)
return
;
for
(
i
=
0
;
i
<
hash
->
size
;
i
++
)
{
head
=
&
hash
->
table
[
i
];
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tt_local_entry
,
node
,
head
,
hash_entry
)
{
tt_local_entry
->
flags
&=
~
flags
;
atomic_inc
(
&
bat_priv
->
num_local_tt
);
}
rcu_read_unlock
();
}
}
/* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
static
void
tt_local_purge_pending_clients
(
struct
bat_priv
*
bat_priv
)
{
struct
hashtable_t
*
hash
=
bat_priv
->
tt_local_hash
;
struct
tt_local_entry
*
tt_local_entry
;
struct
hlist_node
*
node
,
*
node_tmp
;
struct
hlist_head
*
head
;
spinlock_t
*
list_lock
;
/* protects write access to the hash lists */
int
i
;
if
(
!
hash
)
return
;
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
(
tt_local_entry
,
node
,
node_tmp
,
head
,
hash_entry
)
{
if
(
!
(
tt_local_entry
->
flags
&
TT_CLIENT_PENDING
))
continue
;
bat_dbg
(
DBG_TT
,
bat_priv
,
"Deleting local tt entry "
"(%pM): pending
\n
"
,
tt_local_entry
->
addr
);
atomic_dec
(
&
bat_priv
->
num_local_tt
);
hlist_del_rcu
(
node
);
tt_local_entry_free_ref
(
tt_local_entry
);
}
spin_unlock_bh
(
list_lock
);
}
}
void
tt_commit_changes
(
struct
bat_priv
*
bat_priv
)
{
tt_local_reset_flags
(
bat_priv
,
TT_CLIENT_NEW
);
tt_local_purge_pending_clients
(
bat_priv
);
/* Increment the TTVN only once per OGM interval */
atomic_inc
(
&
bat_priv
->
ttvn
);
bat_priv
->
tt_poss_change
=
false
;
}
net/batman-adv/translation-table.h
浏览文件 @
3f9aed7c
...
...
@@ -61,5 +61,6 @@ void handle_tt_response(struct bat_priv *bat_priv,
struct
tt_query_packet
*
tt_response
);
void
send_roam_adv
(
struct
bat_priv
*
bat_priv
,
uint8_t
*
client
,
struct
orig_node
*
orig_node
);
void
tt_commit_changes
(
struct
bat_priv
*
bat_priv
);
#endif
/* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录