Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
f30a7784
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看板
提交
f30a7784
编写于
5月 11, 2010
作者:
P
Patrick McHardy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ipv6: ip6mr: convert struct mfc_cache to struct list_head
Signed-off-by:
N
Patrick McHardy
<
kaber@trash.net
>
上级
b5aa30b1
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
65 addition
and
68 deletion
+65
-68
include/linux/mroute6.h
include/linux/mroute6.h
+1
-1
include/net/netns/ipv6.h
include/net/netns/ipv6.h
+2
-2
net/ipv6/ip6mr.c
net/ipv6/ip6mr.c
+62
-65
未找到文件。
include/linux/mroute6.h
浏览文件 @
f30a7784
...
...
@@ -182,7 +182,7 @@ struct mif_device {
#define VIFF_STATIC 0x8000
struct
mfc6_cache
{
struct
mfc6_cache
*
next
;
/* Next entry on cache line */
struct
list_head
list
;
struct
in6_addr
mf6c_mcastgrp
;
/* Group the entry belongs to */
struct
in6_addr
mf6c_origin
;
/* Source of packet */
mifi_t
mf6c_parent
;
/* Source interface */
...
...
include/net/netns/ipv6.h
浏览文件 @
f30a7784
...
...
@@ -61,8 +61,8 @@ struct netns_ipv6 {
#ifdef CONFIG_IPV6_MROUTE
struct
sock
*
mroute6_sk
;
struct
timer_list
ipmr_expire_timer
;
struct
mfc6_cache
*
mfc6_unres_queue
;
struct
mfc6_cache
*
*
mfc6_cache_array
;
struct
list_head
mfc6_unres_queue
;
struct
list_head
*
mfc6_cache_array
;
struct
mif_device
*
vif6_table
;
int
maxvif
;
atomic_t
cache_resolve_queue_len
;
...
...
net/ipv6/ip6mr.c
浏览文件 @
f30a7784
...
...
@@ -89,7 +89,7 @@ static void mroute_clean_tables(struct net *net);
struct
ipmr_mfc_iter
{
struct
seq_net_private
p
;
struct
mfc6_cache
*
*
cache
;
struct
list_head
*
cache
;
int
ct
;
};
...
...
@@ -99,18 +99,18 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
{
struct
mfc6_cache
*
mfc
;
it
->
cache
=
net
->
ipv6
.
mfc6_cache_array
;
read_lock
(
&
mrt_lock
);
for
(
it
->
ct
=
0
;
it
->
ct
<
MFC6_LINES
;
it
->
ct
++
)
for
(
mfc
=
net
->
ipv6
.
mfc6_cache_array
[
it
->
ct
];
mfc
;
mfc
=
mfc
->
nex
t
)
for
(
it
->
ct
=
0
;
it
->
ct
<
MFC6_LINES
;
it
->
ct
++
)
{
it
->
cache
=
&
net
->
ipv6
.
mfc6_cache_array
[
it
->
ct
];
list_for_each_entry
(
mfc
,
it
->
cache
,
lis
t
)
if
(
pos
--
==
0
)
return
mfc
;
}
read_unlock
(
&
mrt_lock
);
it
->
cache
=
&
net
->
ipv6
.
mfc6_unres_queue
;
spin_lock_bh
(
&
mfc_unres_lock
);
for
(
mfc
=
net
->
ipv6
.
mfc6_unres_queue
;
mfc
;
mfc
=
mfc
->
next
)
it
->
cache
=
&
net
->
ipv6
.
mfc6_unres_queue
;
list_for_each_entry
(
mfc
,
it
->
cache
,
list
)
if
(
pos
--
==
0
)
return
mfc
;
spin_unlock_bh
(
&
mfc_unres_lock
);
...
...
@@ -119,9 +119,6 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
return
NULL
;
}
/*
* The /proc interfaces to multicast routing /proc/ip6_mr_cache /proc/ip6_mr_vif
*/
...
...
@@ -238,18 +235,19 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
if
(
v
==
SEQ_START_TOKEN
)
return
ipmr_mfc_seq_idx
(
net
,
seq
->
private
,
0
);
if
(
mfc
->
next
)
return
mfc
->
next
;
if
(
mfc
->
list
.
next
!=
it
->
cache
)
return
list_entry
(
mfc
->
list
.
next
,
struct
mfc6_cache
,
list
)
;
if
(
it
->
cache
==
&
net
->
ipv6
.
mfc6_unres_queue
)
goto
end_of_list
;
BUG_ON
(
it
->
cache
!=
net
->
ipv6
.
mfc6_cache_array
);
BUG_ON
(
it
->
cache
!=
&
net
->
ipv6
.
mfc6_cache_array
[
it
->
ct
]
);
while
(
++
it
->
ct
<
MFC6_LINES
)
{
mfc
=
net
->
ipv6
.
mfc6_cache_array
[
it
->
ct
];
if
(
mfc
)
return
mfc
;
it
->
cache
=
&
net
->
ipv6
.
mfc6_cache_array
[
it
->
ct
];
if
(
list_empty
(
it
->
cache
))
continue
;
return
list_first_entry
(
it
->
cache
,
struct
mfc6_cache
,
list
);
}
/* exhausted cache_array, show unresolved */
...
...
@@ -258,9 +256,8 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
it
->
ct
=
0
;
spin_lock_bh
(
&
mfc_unres_lock
);
mfc
=
net
->
ipv6
.
mfc6_unres_queue
;
if
(
mfc
)
return
mfc
;
if
(
!
list_empty
(
it
->
cache
))
return
list_first_entry
(
it
->
cache
,
struct
mfc6_cache
,
list
);
end_of_list:
spin_unlock_bh
(
&
mfc_unres_lock
);
...
...
@@ -560,25 +557,22 @@ static void ipmr_do_expire_process(struct net *net)
{
unsigned
long
now
=
jiffies
;
unsigned
long
expires
=
10
*
HZ
;
struct
mfc6_cache
*
c
,
**
cp
;
cp
=
&
net
->
ipv6
.
mfc6_unres_queue
;
struct
mfc6_cache
*
c
,
*
next
;
while
((
c
=
*
cp
)
!=
NULL
)
{
list_for_each_entry_safe
(
c
,
next
,
&
net
->
ipv6
.
mfc6_unres_queue
,
list
)
{
if
(
time_after
(
c
->
mfc_un
.
unres
.
expires
,
now
))
{
/* not yet... */
unsigned
long
interval
=
c
->
mfc_un
.
unres
.
expires
-
now
;
if
(
interval
<
expires
)
expires
=
interval
;
cp
=
&
c
->
next
;
continue
;
}
*
cp
=
c
->
next
;
list_del
(
&
c
->
list
)
;
ip6mr_destroy_unres
(
net
,
c
);
}
if
(
net
->
ipv6
.
mfc6_unres_queue
!=
NULL
)
if
(
!
list_empty
(
&
net
->
ipv6
.
mfc6_unres_queue
)
)
mod_timer
(
&
net
->
ipv6
.
ipmr_expire_timer
,
jiffies
+
expires
);
}
...
...
@@ -591,7 +585,7 @@ static void ipmr_expire_process(unsigned long arg)
return
;
}
if
(
net
->
ipv6
.
mfc6_unres_queue
!=
NULL
)
if
(
!
list_empty
(
&
net
->
ipv6
.
mfc6_unres_queue
)
)
ipmr_do_expire_process
(
net
);
spin_unlock
(
&
mfc_unres_lock
);
...
...
@@ -706,12 +700,12 @@ static struct mfc6_cache *ip6mr_cache_find(struct net *net,
int
line
=
MFC6_HASH
(
mcastgrp
,
origin
);
struct
mfc6_cache
*
c
;
for
(
c
=
net
->
ipv6
.
mfc6_cache_array
[
line
];
c
;
c
=
c
->
nex
t
)
{
list_for_each_entry
(
c
,
&
net
->
ipv6
.
mfc6_cache_array
[
line
],
lis
t
)
{
if
(
ipv6_addr_equal
(
&
c
->
mf6c_origin
,
origin
)
&&
ipv6_addr_equal
(
&
c
->
mf6c_mcastgrp
,
mcastgrp
))
break
;
return
c
;
}
return
c
;
return
NULL
;
}
/*
...
...
@@ -872,17 +866,20 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi,
static
int
ip6mr_cache_unresolved
(
struct
net
*
net
,
mifi_t
mifi
,
struct
sk_buff
*
skb
)
{
bool
found
=
false
;
int
err
;
struct
mfc6_cache
*
c
;
spin_lock_bh
(
&
mfc_unres_lock
);
for
(
c
=
net
->
ipv6
.
mfc6_unres_queue
;
c
;
c
=
c
->
nex
t
)
{
list_for_each_entry
(
c
,
&
net
->
ipv6
.
mfc6_unres_queue
,
lis
t
)
{
if
(
ipv6_addr_equal
(
&
c
->
mf6c_mcastgrp
,
&
ipv6_hdr
(
skb
)
->
daddr
)
&&
ipv6_addr_equal
(
&
c
->
mf6c_origin
,
&
ipv6_hdr
(
skb
)
->
saddr
))
ipv6_addr_equal
(
&
c
->
mf6c_origin
,
&
ipv6_hdr
(
skb
)
->
saddr
))
{
found
=
true
;
break
;
}
}
if
(
c
==
NULL
)
{
if
(
!
found
)
{
/*
* Create a new entry if allowable
*/
...
...
@@ -918,8 +915,7 @@ ip6mr_cache_unresolved(struct net *net, mifi_t mifi, struct sk_buff *skb)
}
atomic_inc
(
&
net
->
ipv6
.
cache_resolve_queue_len
);
c
->
next
=
net
->
ipv6
.
mfc6_unres_queue
;
net
->
ipv6
.
mfc6_unres_queue
=
c
;
list_add
(
&
c
->
list
,
&
net
->
ipv6
.
mfc6_unres_queue
);
ipmr_do_expire_process
(
net
);
}
...
...
@@ -946,16 +942,15 @@ ip6mr_cache_unresolved(struct net *net, mifi_t mifi, struct sk_buff *skb)
static
int
ip6mr_mfc_delete
(
struct
net
*
net
,
struct
mf6cctl
*
mfc
)
{
int
line
;
struct
mfc6_cache
*
c
,
*
*
cp
;
struct
mfc6_cache
*
c
,
*
next
;
line
=
MFC6_HASH
(
&
mfc
->
mf6cc_mcastgrp
.
sin6_addr
,
&
mfc
->
mf6cc_origin
.
sin6_addr
);
for
(
cp
=
&
net
->
ipv6
.
mfc6_cache_array
[
line
];
(
c
=
*
cp
)
!=
NULL
;
cp
=
&
c
->
next
)
{
list_for_each_entry_safe
(
c
,
next
,
&
net
->
ipv6
.
mfc6_cache_array
[
line
],
list
)
{
if
(
ipv6_addr_equal
(
&
c
->
mf6c_origin
,
&
mfc
->
mf6cc_origin
.
sin6_addr
)
&&
ipv6_addr_equal
(
&
c
->
mf6c_mcastgrp
,
&
mfc
->
mf6cc_mcastgrp
.
sin6_addr
))
{
write_lock_bh
(
&
mrt_lock
);
*
cp
=
c
->
next
;
list_del
(
&
c
->
list
)
;
write_unlock_bh
(
&
mrt_lock
);
ip6mr_cache_free
(
c
);
...
...
@@ -997,7 +992,9 @@ static struct notifier_block ip6_mr_notifier = {
static
int
__net_init
ip6mr_net_init
(
struct
net
*
net
)
{
unsigned
int
i
;
int
err
=
0
;
net
->
ipv6
.
vif6_table
=
kcalloc
(
MAXMIFS
,
sizeof
(
struct
mif_device
),
GFP_KERNEL
);
if
(
!
net
->
ipv6
.
vif6_table
)
{
...
...
@@ -1007,13 +1004,18 @@ static int __net_init ip6mr_net_init(struct net *net)
/* Forwarding cache */
net
->
ipv6
.
mfc6_cache_array
=
kcalloc
(
MFC6_LINES
,
sizeof
(
struct
mfc6_cache
*
),
sizeof
(
struct
list_head
),
GFP_KERNEL
);
if
(
!
net
->
ipv6
.
mfc6_cache_array
)
{
err
=
-
ENOMEM
;
goto
fail_mfc6_cache
;
}
for
(
i
=
0
;
i
<
MFC6_LINES
;
i
++
)
INIT_LIST_HEAD
(
&
net
->
ipv6
.
mfc6_cache_array
[
i
]);
INIT_LIST_HEAD
(
&
net
->
ipv6
.
mfc6_unres_queue
);
setup_timer
(
&
net
->
ipv6
.
ipmr_expire_timer
,
ipmr_expire_process
,
(
unsigned
long
)
net
);
...
...
@@ -1105,8 +1107,9 @@ void ip6_mr_cleanup(void)
static
int
ip6mr_mfc_add
(
struct
net
*
net
,
struct
mf6cctl
*
mfc
,
int
mrtsock
)
{
bool
found
=
false
;
int
line
;
struct
mfc6_cache
*
uc
,
*
c
,
**
cp
;
struct
mfc6_cache
*
uc
,
*
c
;
unsigned
char
ttls
[
MAXMIFS
];
int
i
;
...
...
@@ -1122,14 +1125,15 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
line
=
MFC6_HASH
(
&
mfc
->
mf6cc_mcastgrp
.
sin6_addr
,
&
mfc
->
mf6cc_origin
.
sin6_addr
);
for
(
cp
=
&
net
->
ipv6
.
mfc6_cache_array
[
line
];
(
c
=
*
cp
)
!=
NULL
;
cp
=
&
c
->
next
)
{
list_for_each_entry
(
c
,
&
net
->
ipv6
.
mfc6_cache_array
[
line
],
list
)
{
if
(
ipv6_addr_equal
(
&
c
->
mf6c_origin
,
&
mfc
->
mf6cc_origin
.
sin6_addr
)
&&
ipv6_addr_equal
(
&
c
->
mf6c_mcastgrp
,
&
mfc
->
mf6cc_mcastgrp
.
sin6_addr
))
ipv6_addr_equal
(
&
c
->
mf6c_mcastgrp
,
&
mfc
->
mf6cc_mcastgrp
.
sin6_addr
))
{
found
=
true
;
break
;
}
}
if
(
c
!=
NULL
)
{
if
(
found
)
{
write_lock_bh
(
&
mrt_lock
);
c
->
mf6c_parent
=
mfc
->
mf6cc_parent
;
ip6mr_update_thresholds
(
net
,
c
,
ttls
);
...
...
@@ -1154,29 +1158,29 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
c
->
mfc_flags
|=
MFC_STATIC
;
write_lock_bh
(
&
mrt_lock
);
c
->
next
=
net
->
ipv6
.
mfc6_cache_array
[
line
];
net
->
ipv6
.
mfc6_cache_array
[
line
]
=
c
;
list_add
(
&
c
->
list
,
&
net
->
ipv6
.
mfc6_cache_array
[
line
]);
write_unlock_bh
(
&
mrt_lock
);
/*
* Check to see if we resolved a queued list. If so we
* need to send on the frames and tidy up.
*/
found
=
false
;
spin_lock_bh
(
&
mfc_unres_lock
);
for
(
cp
=
&
net
->
ipv6
.
mfc6_unres_queue
;
(
uc
=
*
cp
)
!=
NULL
;
cp
=
&
uc
->
next
)
{
list_for_each_entry
(
uc
,
&
net
->
ipv6
.
mfc6_unres_queue
,
list
)
{
if
(
ipv6_addr_equal
(
&
uc
->
mf6c_origin
,
&
c
->
mf6c_origin
)
&&
ipv6_addr_equal
(
&
uc
->
mf6c_mcastgrp
,
&
c
->
mf6c_mcastgrp
))
{
*
cp
=
uc
->
next
;
list_del
(
&
uc
->
list
)
;
atomic_dec
(
&
net
->
ipv6
.
cache_resolve_queue_len
);
found
=
true
;
break
;
}
}
if
(
net
->
ipv6
.
mfc6_unres_queue
==
NULL
)
if
(
list_empty
(
&
net
->
ipv6
.
mfc6_unres_queue
)
)
del_timer
(
&
net
->
ipv6
.
ipmr_expire_timer
);
spin_unlock_bh
(
&
mfc_unres_lock
);
if
(
uc
)
{
if
(
found
)
{
ip6mr_cache_resolve
(
net
,
uc
,
c
);
ip6mr_cache_free
(
uc
);
}
...
...
@@ -1191,6 +1195,7 @@ static void mroute_clean_tables(struct net *net)
{
int
i
;
LIST_HEAD
(
list
);
struct
mfc6_cache
*
c
,
*
next
;
/*
* Shut down all active vif entries
...
...
@@ -1205,16 +1210,11 @@ static void mroute_clean_tables(struct net *net)
* Wipe the cache
*/
for
(
i
=
0
;
i
<
MFC6_LINES
;
i
++
)
{
struct
mfc6_cache
*
c
,
**
cp
;
cp
=
&
net
->
ipv6
.
mfc6_cache_array
[
i
];
while
((
c
=
*
cp
)
!=
NULL
)
{
if
(
c
->
mfc_flags
&
MFC_STATIC
)
{
cp
=
&
c
->
next
;
list_for_each_entry_safe
(
c
,
next
,
&
net
->
ipv6
.
mfc6_cache_array
[
i
],
list
)
{
if
(
c
->
mfc_flags
&
MFC_STATIC
)
continue
;
}
write_lock_bh
(
&
mrt_lock
);
*
cp
=
c
->
next
;
list_del
(
&
c
->
list
)
;
write_unlock_bh
(
&
mrt_lock
);
ip6mr_cache_free
(
c
);
...
...
@@ -1222,12 +1222,9 @@ static void mroute_clean_tables(struct net *net)
}
if
(
atomic_read
(
&
net
->
ipv6
.
cache_resolve_queue_len
)
!=
0
)
{
struct
mfc6_cache
*
c
,
**
cp
;
spin_lock_bh
(
&
mfc_unres_lock
);
cp
=
&
net
->
ipv6
.
mfc6_unres_queue
;
while
((
c
=
*
cp
)
!=
NULL
)
{
*
cp
=
c
->
next
;
list_for_each_entry_safe
(
c
,
next
,
&
net
->
ipv6
.
mfc6_unres_queue
,
list
)
{
list_del
(
&
c
->
list
);
ip6mr_destroy_unres
(
net
,
c
);
}
spin_unlock_bh
(
&
mfc_unres_lock
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录