Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bug2833
cloud-kernel
提交
16fb62b6
cloud-kernel
项目概览
bug2833
/
cloud-kernel
与 Fork 源项目一致
Fork自
openanolis / cloud-kernel
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
16fb62b6
编写于
6月 15, 2010
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
上级
a3433f35
f9181f4f
变更
36
隐藏空白更改
内联
并排
Showing
36 changed file
with
608 addition
and
205 deletion
+608
-205
include/linux/netfilter/Kbuild
include/linux/netfilter/Kbuild
+1
-0
include/linux/netfilter/nf_conntrack_common.h
include/linux/netfilter/nf_conntrack_common.h
+4
-0
include/linux/netfilter/nfnetlink_log.h
include/linux/netfilter/nfnetlink_log.h
+1
-0
include/linux/netfilter/xt_IDLETIMER.h
include/linux/netfilter/xt_IDLETIMER.h
+45
-0
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack.h
+8
-3
include/net/netfilter/nf_conntrack_core.h
include/net/netfilter/nf_conntrack_core.h
+1
-1
include/net/netfilter/xt_rateest.h
include/net/netfilter/xt_rateest.h
+7
-3
net/bridge/br_netfilter.c
net/bridge/br_netfilter.c
+2
-4
net/ipv4/netfilter.c
net/ipv4/netfilter.c
+1
-3
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arp_tables.c
+3
-4
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_queue.c
+25
-32
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ip_tables.c
+2
-2
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
+29
-19
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_core.c
+1
-1
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/netfilter/nf_nat_standalone.c
+1
-1
net/ipv6/netfilter.c
net/ipv6/netfilter.c
+1
-3
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_queue.c
+25
-32
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6_tables.c
+3
-4
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+1
-1
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/netfilter/nf_conntrack_reasm.c
+3
-6
net/netfilter/Kconfig
net/netfilter/Kconfig
+12
-0
net/netfilter/Makefile
net/netfilter/Makefile
+1
-0
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_core.c
+31
-9
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_netlink.c
+1
-1
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_log.c
+39
-28
net/netfilter/nfnetlink_queue.c
net/netfilter/nfnetlink_queue.c
+14
-19
net/netfilter/xt_CT.c
net/netfilter/xt_CT.c
+2
-2
net/netfilter/xt_IDLETIMER.c
net/netfilter/xt_IDLETIMER.c
+314
-0
net/netfilter/xt_NOTRACK.c
net/netfilter/xt_NOTRACK.c
+1
-1
net/netfilter/xt_TEE.c
net/netfilter/xt_TEE.c
+2
-2
net/netfilter/xt_cluster.c
net/netfilter/xt_cluster.c
+1
-1
net/netfilter/xt_conntrack.c
net/netfilter/xt_conntrack.c
+6
-5
net/netfilter/xt_sctp.c
net/netfilter/xt_sctp.c
+2
-1
net/netfilter/xt_socket.c
net/netfilter/xt_socket.c
+1
-1
net/netfilter/xt_state.c
net/netfilter/xt_state.c
+8
-6
net/netfilter/xt_statistic.c
net/netfilter/xt_statistic.c
+9
-10
未找到文件。
include/linux/netfilter/Kbuild
浏览文件 @
16fb62b6
...
...
@@ -8,6 +8,7 @@ header-y += xt_CONNMARK.h
header-y += xt_CONNSECMARK.h
header-y += xt_CT.h
header-y += xt_DSCP.h
header-y += xt_IDLETIMER.h
header-y += xt_LED.h
header-y += xt_MARK.h
header-y += xt_NFLOG.h
...
...
include/linux/netfilter/nf_conntrack_common.h
浏览文件 @
16fb62b6
...
...
@@ -76,6 +76,10 @@ enum ip_conntrack_status {
/* Conntrack is a template */
IPS_TEMPLATE_BIT
=
11
,
IPS_TEMPLATE
=
(
1
<<
IPS_TEMPLATE_BIT
),
/* Conntrack is a fake untracked entry */
IPS_UNTRACKED_BIT
=
12
,
IPS_UNTRACKED
=
(
1
<<
IPS_UNTRACKED_BIT
),
};
/* Connection tracking event types */
...
...
include/linux/netfilter/nfnetlink_log.h
浏览文件 @
16fb62b6
...
...
@@ -89,6 +89,7 @@ enum nfulnl_attr_config {
#define NFULNL_COPY_NONE 0x00
#define NFULNL_COPY_META 0x01
#define NFULNL_COPY_PACKET 0x02
#define NFULNL_COPY_DISABLED 0x03
#define NFULNL_CFG_F_SEQ 0x0001
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
...
...
include/linux/netfilter/xt_IDLETIMER.h
0 → 100644
浏览文件 @
16fb62b6
/*
* linux/include/linux/netfilter/xt_IDLETIMER.h
*
* Header file for Xtables timer target module.
*
* Copyright (C) 2004, 2010 Nokia Corporation
* Written by Timo Teras <ext-timo.teras@nokia.com>
*
* Converted to x_tables and forward-ported to 2.6.34
* by Luciano Coelho <luciano.coelho@nokia.com>
*
* Contact: Luciano Coelho <luciano.coelho@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef _XT_IDLETIMER_H
#define _XT_IDLETIMER_H
#include <linux/types.h>
#define MAX_IDLETIMER_LABEL_SIZE 28
struct
idletimer_tg_info
{
__u32
timeout
;
char
label
[
MAX_IDLETIMER_LABEL_SIZE
];
/* for kernel module internal use only */
struct
idletimer_tg
*
timer
__attribute
((
aligned
(
8
)));
};
#endif
include/net/netfilter/nf_conntrack.h
浏览文件 @
16fb62b6
...
...
@@ -257,7 +257,12 @@ extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
u32
seq
);
/* Fake conntrack entry for untracked connections */
extern
struct
nf_conn
nf_conntrack_untracked
;
DECLARE_PER_CPU
(
struct
nf_conn
,
nf_conntrack_untracked
);
static
inline
struct
nf_conn
*
nf_ct_untracked_get
(
void
)
{
return
&
__raw_get_cpu_var
(
nf_conntrack_untracked
);
}
extern
void
nf_ct_untracked_status_or
(
unsigned
long
bits
);
/* Iterate over all conntracks: if iter returns true, it's deleted. */
extern
void
...
...
@@ -285,9 +290,9 @@ static inline int nf_ct_is_dying(struct nf_conn *ct)
return
test_bit
(
IPS_DYING_BIT
,
&
ct
->
status
);
}
static
inline
int
nf_ct_is_untracked
(
const
struct
sk_buff
*
skb
)
static
inline
int
nf_ct_is_untracked
(
const
struct
nf_conn
*
ct
)
{
return
(
skb
->
nfct
==
&
nf_conntrack_untracked
.
ct_general
);
return
test_bit
(
IPS_UNTRACKED_BIT
,
&
ct
->
status
);
}
extern
int
nf_conntrack_set_hashsize
(
const
char
*
val
,
struct
kernel_param
*
kp
);
...
...
include/net/netfilter/nf_conntrack_core.h
浏览文件 @
16fb62b6
...
...
@@ -60,7 +60,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
struct
nf_conn
*
ct
=
(
struct
nf_conn
*
)
skb
->
nfct
;
int
ret
=
NF_ACCEPT
;
if
(
ct
&&
ct
!=
&
nf_conntrack_untracked
)
{
if
(
ct
&&
!
nf_ct_is_untracked
(
ct
)
)
{
if
(
!
nf_ct_is_confirmed
(
ct
))
ret
=
__nf_conntrack_confirm
(
skb
);
if
(
likely
(
ret
==
NF_ACCEPT
))
...
...
include/net/netfilter/xt_rateest.h
浏览文件 @
16fb62b6
...
...
@@ -2,13 +2,17 @@
#define _XT_RATEEST_H
struct
xt_rateest
{
/* keep lock and bstats on same cache line to speedup xt_rateest_tg() */
struct
gnet_stats_basic_packed
bstats
;
spinlock_t
lock
;
/* keep rstats and lock on same cache line to speedup xt_rateest_mt() */
struct
gnet_stats_rate_est
rstats
;
/* following fields not accessed in hot path */
struct
hlist_node
list
;
char
name
[
IFNAMSIZ
];
unsigned
int
refcnt
;
spinlock_t
lock
;
struct
gnet_estimator
params
;
struct
gnet_stats_rate_est
rstats
;
struct
gnet_stats_basic_packed
bstats
;
struct
rcu_head
rcu
;
};
...
...
net/bridge/br_netfilter.c
浏览文件 @
16fb62b6
...
...
@@ -245,8 +245,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
kfree_skb
(
skb
);
return
0
;
}
dst_hold
(
&
rt
->
dst
);
skb_dst_set
(
skb
,
&
rt
->
dst
);
skb_dst_set_noref
(
skb
,
&
rt
->
dst
);
skb
->
dev
=
nf_bridge
->
physindev
;
nf_bridge_update_protocol
(
skb
);
...
...
@@ -397,8 +396,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
kfree_skb
(
skb
);
return
0
;
}
dst_hold
(
&
rt
->
dst
);
skb_dst_set
(
skb
,
&
rt
->
dst
);
skb_dst_set_noref
(
skb
,
&
rt
->
dst
);
}
skb
->
dev
=
nf_bridge
->
physindev
;
...
...
net/ipv4/netfilter.c
浏览文件 @
16fb62b6
...
...
@@ -212,9 +212,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
skb
->
csum
=
csum_tcpudp_nofold
(
iph
->
saddr
,
iph
->
daddr
,
protocol
,
skb
->
len
-
dataoff
,
0
);
skb
->
ip_summed
=
CHECKSUM_NONE
;
csum
=
__skb_checksum_complete_head
(
skb
,
dataoff
+
len
);
if
(
!
csum
)
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
return
__skb_checksum_complete_head
(
skb
,
dataoff
+
len
);
}
return
csum
;
}
...
...
net/ipv4/netfilter/arp_tables.c
浏览文件 @
16fb62b6
...
...
@@ -758,7 +758,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table)
* about).
*/
countersize
=
sizeof
(
struct
xt_counters
)
*
private
->
number
;
counters
=
vmalloc
_node
(
countersize
,
numa_node_id
()
);
counters
=
vmalloc
(
countersize
);
if
(
counters
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
...
...
@@ -1005,8 +1005,7 @@ static int __do_replace(struct net *net, const char *name,
struct
arpt_entry
*
iter
;
ret
=
0
;
counters
=
vmalloc_node
(
num_counters
*
sizeof
(
struct
xt_counters
),
numa_node_id
());
counters
=
vmalloc
(
num_counters
*
sizeof
(
struct
xt_counters
));
if
(
!
counters
)
{
ret
=
-
ENOMEM
;
goto
out
;
...
...
@@ -1159,7 +1158,7 @@ static int do_add_counters(struct net *net, const void __user *user,
if
(
len
!=
size
+
num_counters
*
sizeof
(
struct
xt_counters
))
return
-
EINVAL
;
paddc
=
vmalloc
_node
(
len
-
size
,
numa_node_id
()
);
paddc
=
vmalloc
(
len
-
size
);
if
(
!
paddc
)
return
-
ENOMEM
;
...
...
net/ipv4/netfilter/ip_queue.c
浏览文件 @
16fb62b6
...
...
@@ -42,7 +42,7 @@ typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long);
static
unsigned
char
copy_mode
__read_mostly
=
IPQ_COPY_NONE
;
static
unsigned
int
queue_maxlen
__read_mostly
=
IPQ_QMAX_DEFAULT
;
static
DEFINE_
RW
LOCK
(
queue_lock
);
static
DEFINE_
SPIN
LOCK
(
queue_lock
);
static
int
peer_pid
__read_mostly
;
static
unsigned
int
copy_range
__read_mostly
;
static
unsigned
int
queue_total
;
...
...
@@ -72,10 +72,10 @@ __ipq_set_mode(unsigned char mode, unsigned int range)
break
;
case
IPQ_COPY_PACKET
:
copy_mode
=
mode
;
if
(
range
>
0xFFFF
)
range
=
0xFFFF
;
copy_range
=
range
;
if
(
copy_range
>
0xFFFF
)
copy_range
=
0xFFFF
;
copy_mode
=
mode
;
break
;
default:
...
...
@@ -101,7 +101,7 @@ ipq_find_dequeue_entry(unsigned long id)
{
struct
nf_queue_entry
*
entry
=
NULL
,
*
i
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
list_for_each_entry
(
i
,
&
queue_list
,
list
)
{
if
((
unsigned
long
)
i
==
id
)
{
...
...
@@ -115,7 +115,7 @@ ipq_find_dequeue_entry(unsigned long id)
queue_total
--
;
}
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
entry
;
}
...
...
@@ -136,9 +136,9 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
static
void
ipq_flush
(
ipq_cmpfn
cmpfn
,
unsigned
long
data
)
{
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
__ipq_flush
(
cmpfn
,
data
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
}
static
struct
sk_buff
*
...
...
@@ -152,9 +152,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
struct
nlmsghdr
*
nlh
;
struct
timeval
tv
;
read_lock_bh
(
&
queue_lock
);
switch
(
copy_mode
)
{
switch
(
ACCESS_ONCE
(
copy_mode
))
{
case
IPQ_COPY_META
:
case
IPQ_COPY_NONE
:
size
=
NLMSG_SPACE
(
sizeof
(
*
pmsg
));
...
...
@@ -162,26 +160,21 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
case
IPQ_COPY_PACKET
:
if
(
entry
->
skb
->
ip_summed
==
CHECKSUM_PARTIAL
&&
(
*
errp
=
skb_checksum_help
(
entry
->
skb
)))
{
read_unlock_bh
(
&
queue_lock
);
(
*
errp
=
skb_checksum_help
(
entry
->
skb
)))
return
NULL
;
}
if
(
copy_range
==
0
||
copy_range
>
entry
->
skb
->
len
)
data_len
=
ACCESS_ONCE
(
copy_range
);
if
(
data_len
==
0
||
data_len
>
entry
->
skb
->
len
)
data_len
=
entry
->
skb
->
len
;
else
data_len
=
copy_range
;
size
=
NLMSG_SPACE
(
sizeof
(
*
pmsg
)
+
data_len
);
break
;
default:
*
errp
=
-
EINVAL
;
read_unlock_bh
(
&
queue_lock
);
return
NULL
;
}
read_unlock_bh
(
&
queue_lock
);
skb
=
alloc_skb
(
size
,
GFP_ATOMIC
);
if
(
!
skb
)
goto
nlmsg_failure
;
...
...
@@ -242,7 +235,7 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
if
(
nskb
==
NULL
)
return
status
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
(
!
peer_pid
)
goto
err_out_free_nskb
;
...
...
@@ -266,14 +259,14 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
__ipq_enqueue_entry
(
entry
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
err_out_free_nskb:
kfree_skb
(
nskb
);
err_out_unlock:
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
}
...
...
@@ -342,9 +335,9 @@ ipq_set_mode(unsigned char mode, unsigned int range)
{
int
status
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
status
=
__ipq_set_mode
(
mode
,
range
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
}
...
...
@@ -440,11 +433,11 @@ __ipq_rcv_skb(struct sk_buff *skb)
if
(
security_netlink_recv
(
skb
,
CAP_NET_ADMIN
))
RCV_SKB_FAIL
(
-
EPERM
);
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
(
peer_pid
)
{
if
(
peer_pid
!=
pid
)
{
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
RCV_SKB_FAIL
(
-
EBUSY
);
}
}
else
{
...
...
@@ -452,7 +445,7 @@ __ipq_rcv_skb(struct sk_buff *skb)
peer_pid
=
pid
;
}
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
status
=
ipq_receive_peer
(
NLMSG_DATA
(
nlh
),
type
,
nlmsglen
-
NLMSG_LENGTH
(
0
));
...
...
@@ -497,10 +490,10 @@ ipq_rcv_nl_event(struct notifier_block *this,
struct
netlink_notify
*
n
=
ptr
;
if
(
event
==
NETLINK_URELEASE
&&
n
->
protocol
==
NETLINK_FIREWALL
)
{
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
((
net_eq
(
n
->
net
,
&
init_net
))
&&
(
n
->
pid
==
peer_pid
))
__ipq_reset
();
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
}
return
NOTIFY_DONE
;
}
...
...
@@ -527,7 +520,7 @@ static ctl_table ipq_table[] = {
#ifdef CONFIG_PROC_FS
static
int
ip_queue_show
(
struct
seq_file
*
m
,
void
*
v
)
{
read
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
seq_printf
(
m
,
"Peer PID : %d
\n
"
...
...
@@ -545,7 +538,7 @@ static int ip_queue_show(struct seq_file *m, void *v)
queue_dropped
,
queue_user_dropped
);
read
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
0
;
}
...
...
net/ipv4/netfilter/ip_tables.c
浏览文件 @
16fb62b6
...
...
@@ -928,7 +928,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table)
(other than comefrom, which userspace doesn't care
about). */
countersize
=
sizeof
(
struct
xt_counters
)
*
private
->
number
;
counters
=
vmalloc
_node
(
countersize
,
numa_node_id
()
);
counters
=
vmalloc
(
countersize
);
if
(
counters
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
...
...
@@ -1352,7 +1352,7 @@ do_add_counters(struct net *net, const void __user *user,
if
(
len
!=
size
+
num_counters
*
sizeof
(
struct
xt_counters
))
return
-
EINVAL
;
paddc
=
vmalloc
_node
(
len
-
size
,
numa_node_id
()
);
paddc
=
vmalloc
(
len
-
size
);
if
(
!
paddc
)
return
-
ENOMEM
;
...
...
net/ipv4/netfilter/ipt_CLUSTERIP.c
浏览文件 @
16fb62b6
...
...
@@ -53,12 +53,13 @@ struct clusterip_config {
#endif
enum
clusterip_hashmode
hash_mode
;
/* which hashing mode */
u_int32_t
hash_initval
;
/* hash initialization */
struct
rcu_head
rcu
;
};
static
LIST_HEAD
(
clusterip_configs
);
/* clusterip_lock protects the clusterip_configs list */
static
DEFINE_
RW
LOCK
(
clusterip_lock
);
static
DEFINE_
SPIN
LOCK
(
clusterip_lock
);
#ifdef CONFIG_PROC_FS
static
const
struct
file_operations
clusterip_proc_fops
;
...
...
@@ -71,11 +72,17 @@ clusterip_config_get(struct clusterip_config *c)
atomic_inc
(
&
c
->
refcount
);
}
static
void
clusterip_config_rcu_free
(
struct
rcu_head
*
head
)
{
kfree
(
container_of
(
head
,
struct
clusterip_config
,
rcu
));
}
static
inline
void
clusterip_config_put
(
struct
clusterip_config
*
c
)
{
if
(
atomic_dec_and_test
(
&
c
->
refcount
))
kfree
(
c
);
call_rcu_bh
(
&
c
->
rcu
,
clusterip_config_rcu_free
);
}
/* decrease the count of entries using/referencing this config. If last
...
...
@@ -84,10 +91,11 @@ clusterip_config_put(struct clusterip_config *c)
static
inline
void
clusterip_config_entry_put
(
struct
clusterip_config
*
c
)
{
write_lock_bh
(
&
clusterip_lock
);
if
(
atomic_dec_and_test
(
&
c
->
entries
))
{
list_del
(
&
c
->
list
);
write_unlock_bh
(
&
clusterip_lock
);
local_bh_disable
();
if
(
atomic_dec_and_lock
(
&
c
->
entries
,
&
clusterip_lock
))
{
list_del_rcu
(
&
c
->
list
);
spin_unlock
(
&
clusterip_lock
);
local_bh_enable
();
dev_mc_del
(
c
->
dev
,
c
->
clustermac
);
dev_put
(
c
->
dev
);
...
...
@@ -100,7 +108,7 @@ clusterip_config_entry_put(struct clusterip_config *c)
#endif
return
;
}
write_unlock_bh
(
&
clusterip_lock
);
local_bh_enable
(
);
}
static
struct
clusterip_config
*
...
...
@@ -108,7 +116,7 @@ __clusterip_config_find(__be32 clusterip)
{
struct
clusterip_config
*
c
;
list_for_each_entry
(
c
,
&
clusterip_configs
,
list
)
{
list_for_each_entry
_rcu
(
c
,
&
clusterip_configs
,
list
)
{
if
(
c
->
clusterip
==
clusterip
)
return
c
;
}
...
...
@@ -121,16 +129,15 @@ clusterip_config_find_get(__be32 clusterip, int entry)
{
struct
clusterip_config
*
c
;
r
ead_lock_bh
(
&
clusterip_lock
);
r
cu_read_lock_bh
(
);
c
=
__clusterip_config_find
(
clusterip
);
if
(
!
c
)
{
read_unlock_bh
(
&
clusterip_lock
);
return
NULL
;
if
(
c
)
{
if
(
unlikely
(
!
atomic_inc_not_zero
(
&
c
->
refcount
)))
c
=
NULL
;
else
if
(
entry
)
atomic_inc
(
&
c
->
entries
);
}
atomic_inc
(
&
c
->
refcount
);
if
(
entry
)
atomic_inc
(
&
c
->
entries
);
read_unlock_bh
(
&
clusterip_lock
);
rcu_read_unlock_bh
();
return
c
;
}
...
...
@@ -181,9 +188,9 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
}
#endif
write
_lock_bh
(
&
clusterip_lock
);
list_add
(
&
c
->
list
,
&
clusterip_configs
);
write
_unlock_bh
(
&
clusterip_lock
);
spin
_lock_bh
(
&
clusterip_lock
);
list_add
_rcu
(
&
c
->
list
,
&
clusterip_configs
);
spin
_unlock_bh
(
&
clusterip_lock
);
return
c
;
}
...
...
@@ -733,6 +740,9 @@ static void __exit clusterip_tg_exit(void)
#endif
nf_unregister_hook
(
&
cip_arp_ops
);
xt_unregister_target
(
&
clusterip_tg_reg
);
/* Wait for completion of call_rcu_bh()'s (clusterip_config_rcu_free) */
rcu_barrier_bh
();
}
module_init
(
clusterip_tg_init
);
...
...
net/ipv4/netfilter/nf_nat_core.c
浏览文件 @
16fb62b6
...
...
@@ -742,7 +742,7 @@ static int __init nf_nat_init(void)
spin_unlock_bh
(
&
nf_nat_lock
);
/* Initialize fake conntrack so that NAT will skip it */
nf_c
onntrack_untracked
.
status
|=
IPS_NAT_DONE_MASK
;
nf_c
t_untracked_status_or
(
IPS_NAT_DONE_MASK
)
;
l3proto
=
nf_ct_l3proto_find_get
((
u_int16_t
)
AF_INET
);
...
...
net/ipv4/netfilter/nf_nat_standalone.c
浏览文件 @
16fb62b6
...
...
@@ -98,7 +98,7 @@ nf_nat_fn(unsigned int hooknum,
return
NF_ACCEPT
;
/* Don't try to NAT if this packet is not conntracked */
if
(
ct
==
&
nf_conntrack_untracked
)
if
(
nf_ct_is_untracked
(
ct
)
)
return
NF_ACCEPT
;
nat
=
nfct_nat
(
ct
);
...
...
net/ipv6/netfilter.c
浏览文件 @
16fb62b6
...
...
@@ -151,9 +151,7 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
protocol
,
csum_sub
(
0
,
hsum
)));
skb
->
ip_summed
=
CHECKSUM_NONE
;
csum
=
__skb_checksum_complete_head
(
skb
,
dataoff
+
len
);
if
(
!
csum
)
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
return
__skb_checksum_complete_head
(
skb
,
dataoff
+
len
);
}
return
csum
;
};
...
...
net/ipv6/netfilter/ip6_queue.c
浏览文件 @
16fb62b6
...
...
@@ -43,7 +43,7 @@ typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long);
static
unsigned
char
copy_mode
__read_mostly
=
IPQ_COPY_NONE
;
static
unsigned
int
queue_maxlen
__read_mostly
=
IPQ_QMAX_DEFAULT
;
static
DEFINE_
RW
LOCK
(
queue_lock
);
static
DEFINE_
SPIN
LOCK
(
queue_lock
);
static
int
peer_pid
__read_mostly
;
static
unsigned
int
copy_range
__read_mostly
;
static
unsigned
int
queue_total
;
...
...
@@ -73,10 +73,10 @@ __ipq_set_mode(unsigned char mode, unsigned int range)
break
;
case
IPQ_COPY_PACKET
:
copy_mode
=
mode
;
if
(
range
>
0xFFFF
)
range
=
0xFFFF
;
copy_range
=
range
;
if
(
copy_range
>
0xFFFF
)
copy_range
=
0xFFFF
;
copy_mode
=
mode
;
break
;
default:
...
...
@@ -102,7 +102,7 @@ ipq_find_dequeue_entry(unsigned long id)
{
struct
nf_queue_entry
*
entry
=
NULL
,
*
i
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
list_for_each_entry
(
i
,
&
queue_list
,
list
)
{
if
((
unsigned
long
)
i
==
id
)
{
...
...
@@ -116,7 +116,7 @@ ipq_find_dequeue_entry(unsigned long id)
queue_total
--
;
}
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
entry
;
}
...
...
@@ -137,9 +137,9 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
static
void
ipq_flush
(
ipq_cmpfn
cmpfn
,
unsigned
long
data
)
{
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
__ipq_flush
(
cmpfn
,
data
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
}
static
struct
sk_buff
*
...
...
@@ -153,9 +153,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
struct
nlmsghdr
*
nlh
;
struct
timeval
tv
;
read_lock_bh
(
&
queue_lock
);
switch
(
copy_mode
)
{
switch
(
ACCESS_ONCE
(
copy_mode
))
{
case
IPQ_COPY_META
:
case
IPQ_COPY_NONE
:
size
=
NLMSG_SPACE
(
sizeof
(
*
pmsg
));
...
...
@@ -163,26 +161,21 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
case
IPQ_COPY_PACKET
:
if
(
entry
->
skb
->
ip_summed
==
CHECKSUM_PARTIAL
&&
(
*
errp
=
skb_checksum_help
(
entry
->
skb
)))
{
read_unlock_bh
(
&
queue_lock
);
(
*
errp
=
skb_checksum_help
(
entry
->
skb
)))
return
NULL
;
}
if
(
copy_range
==
0
||
copy_range
>
entry
->
skb
->
len
)
data_len
=
ACCESS_ONCE
(
copy_range
);
if
(
data_len
==
0
||
data_len
>
entry
->
skb
->
len
)
data_len
=
entry
->
skb
->
len
;
else
data_len
=
copy_range
;
size
=
NLMSG_SPACE
(
sizeof
(
*
pmsg
)
+
data_len
);
break
;
default:
*
errp
=
-
EINVAL
;
read_unlock_bh
(
&
queue_lock
);
return
NULL
;
}
read_unlock_bh
(
&
queue_lock
);
skb
=
alloc_skb
(
size
,
GFP_ATOMIC
);
if
(
!
skb
)
goto
nlmsg_failure
;
...
...
@@ -242,7 +235,7 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
if
(
nskb
==
NULL
)
return
status
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
(
!
peer_pid
)
goto
err_out_free_nskb
;
...
...
@@ -266,14 +259,14 @@ ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
__ipq_enqueue_entry
(
entry
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
err_out_free_nskb:
kfree_skb
(
nskb
);
err_out_unlock:
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
}
...
...
@@ -342,9 +335,9 @@ ipq_set_mode(unsigned char mode, unsigned int range)
{
int
status
;
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
status
=
__ipq_set_mode
(
mode
,
range
);
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
status
;
}
...
...
@@ -441,11 +434,11 @@ __ipq_rcv_skb(struct sk_buff *skb)
if
(
security_netlink_recv
(
skb
,
CAP_NET_ADMIN
))
RCV_SKB_FAIL
(
-
EPERM
);
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
(
peer_pid
)
{
if
(
peer_pid
!=
pid
)
{
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
RCV_SKB_FAIL
(
-
EBUSY
);
}
}
else
{
...
...
@@ -453,7 +446,7 @@ __ipq_rcv_skb(struct sk_buff *skb)
peer_pid
=
pid
;
}
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
status
=
ipq_receive_peer
(
NLMSG_DATA
(
nlh
),
type
,
nlmsglen
-
NLMSG_LENGTH
(
0
));
...
...
@@ -498,10 +491,10 @@ ipq_rcv_nl_event(struct notifier_block *this,
struct
netlink_notify
*
n
=
ptr
;
if
(
event
==
NETLINK_URELEASE
&&
n
->
protocol
==
NETLINK_IP6_FW
)
{
write
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
if
((
net_eq
(
n
->
net
,
&
init_net
))
&&
(
n
->
pid
==
peer_pid
))
__ipq_reset
();
write
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
}
return
NOTIFY_DONE
;
}
...
...
@@ -528,7 +521,7 @@ static ctl_table ipq_table[] = {
#ifdef CONFIG_PROC_FS
static
int
ip6_queue_show
(
struct
seq_file
*
m
,
void
*
v
)
{
read
_lock_bh
(
&
queue_lock
);
spin
_lock_bh
(
&
queue_lock
);
seq_printf
(
m
,
"Peer PID : %d
\n
"
...
...
@@ -546,7 +539,7 @@ static int ip6_queue_show(struct seq_file *m, void *v)
queue_dropped
,
queue_user_dropped
);
read
_unlock_bh
(
&
queue_lock
);
spin
_unlock_bh
(
&
queue_lock
);
return
0
;
}
...
...
net/ipv6/netfilter/ip6_tables.c
浏览文件 @
16fb62b6
...
...
@@ -943,7 +943,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table)
(other than comefrom, which userspace doesn't care
about). */
countersize
=
sizeof
(
struct
xt_counters
)
*
private
->
number
;
counters
=
vmalloc
_node
(
countersize
,
numa_node_id
()
);
counters
=
vmalloc
(
countersize
);
if
(
counters
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
...
...
@@ -1213,8 +1213,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct
ip6t_entry
*
iter
;
ret
=
0
;
counters
=
vmalloc_node
(
num_counters
*
sizeof
(
struct
xt_counters
),
numa_node_id
());
counters
=
vmalloc
(
num_counters
*
sizeof
(
struct
xt_counters
));
if
(
!
counters
)
{
ret
=
-
ENOMEM
;
goto
out
;
...
...
@@ -1368,7 +1367,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
if
(
len
!=
size
+
num_counters
*
sizeof
(
struct
xt_counters
))
return
-
EINVAL
;
paddc
=
vmalloc
_node
(
len
-
size
,
numa_node_id
()
);
paddc
=
vmalloc
(
len
-
size
);
if
(
!
paddc
)
return
-
ENOMEM
;
...
...
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
浏览文件 @
16fb62b6
...
...
@@ -208,7 +208,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl,
type
=
icmp6h
->
icmp6_type
-
130
;
if
(
type
>=
0
&&
type
<
sizeof
(
noct_valid_new
)
&&
noct_valid_new
[
type
])
{
skb
->
nfct
=
&
nf_c
onntrack_untracked
.
ct_general
;
skb
->
nfct
=
&
nf_c
t_untracked_get
()
->
ct_general
;
skb
->
nfctinfo
=
IP_CT_NEW
;
nf_conntrack_get
(
skb
->
nfct
);
return
NF_ACCEPT
;
...
...
net/ipv6/netfilter/nf_conntrack_reasm.c
浏览文件 @
16fb62b6
...
...
@@ -114,10 +114,8 @@ static void nf_skb_free(struct sk_buff *skb)
}
/* Memory Tracking Functions. */
static
inline
void
frag_kfree_skb
(
struct
sk_buff
*
skb
,
unsigned
int
*
work
)
static
void
frag_kfree_skb
(
struct
sk_buff
*
skb
)
{
if
(
work
)
*
work
-=
skb
->
truesize
;
atomic_sub
(
skb
->
truesize
,
&
nf_init_frags
.
mem
);
nf_skb_free
(
skb
);
kfree_skb
(
skb
);
...
...
@@ -335,7 +333,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
fq
->
q
.
fragments
=
next
;
fq
->
q
.
meat
-=
free_it
->
len
;
frag_kfree_skb
(
free_it
,
NULL
);
frag_kfree_skb
(
free_it
);
}
}
...
...
@@ -442,7 +440,6 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
skb_shinfo
(
head
)
->
frag_list
=
head
->
next
;
skb_reset_transport_header
(
head
);
skb_push
(
head
,
head
->
data
-
skb_network_header
(
head
));
atomic_sub
(
head
->
truesize
,
&
nf_init_frags
.
mem
);
for
(
fp
=
head
->
next
;
fp
;
fp
=
fp
->
next
)
{
head
->
data_len
+=
fp
->
len
;
...
...
@@ -452,8 +449,8 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
else
if
(
head
->
ip_summed
==
CHECKSUM_COMPLETE
)
head
->
csum
=
csum_add
(
head
->
csum
,
fp
->
csum
);
head
->
truesize
+=
fp
->
truesize
;
atomic_sub
(
fp
->
truesize
,
&
nf_init_frags
.
mem
);
}
atomic_sub
(
head
->
truesize
,
&
nf_init_frags
.
mem
);
head
->
next
=
NULL
;
head
->
dev
=
dev
;
...
...
net/netfilter/Kconfig
浏览文件 @
16fb62b6
...
...
@@ -424,6 +424,18 @@ config NETFILTER_XT_TARGET_HL
since you can easily create immortal packets that loop
forever on the network.
config NETFILTER_XT_TARGET_IDLETIMER
tristate "IDLETIMER target support"
depends on NETFILTER_ADVANCED
help
This option adds the `IDLETIMER' target. Each matching packet
resets the timer associated with label specified when the rule is
added. When the timer expires, it triggers a sysfs notification.
The remaining time for expiration can be read via sysfs.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_LED
tristate '"LED" target support'
depends on LEDS_CLASS && LEDS_TRIGGERS
...
...
net/netfilter/Makefile
浏览文件 @
16fb62b6
...
...
@@ -61,6 +61,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP)
+=
xt_TCPOPTSTRIP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TEE)
+=
xt_TEE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE)
+=
xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER)
+=
xt_IDLETIMER.o
# matches
obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER)
+=
xt_cluster.o
...
...
net/netfilter/nf_conntrack_core.c
浏览文件 @
16fb62b6
...
...
@@ -62,8 +62,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
unsigned
int
nf_conntrack_max
__read_mostly
;
EXPORT_SYMBOL_GPL
(
nf_conntrack_max
);
struct
nf_conn
nf_conntrack_untracked
__read_mostly
;
EXPORT_
SYMBOL_GP
L
(
nf_conntrack_untracked
);
DEFINE_PER_CPU
(
struct
nf_conn
,
nf_conntrack_untracked
)
;
EXPORT_
PER_CPU_SYMBO
L
(
nf_conntrack_untracked
);
static
int
nf_conntrack_hash_rnd_initted
;
static
unsigned
int
nf_conntrack_hash_rnd
;
...
...
@@ -1181,10 +1181,21 @@ static void nf_ct_release_dying_list(struct net *net)
spin_unlock_bh
(
&
nf_conntrack_lock
);
}
static
int
untrack_refs
(
void
)
{
int
cnt
=
0
,
cpu
;
for_each_possible_cpu
(
cpu
)
{
struct
nf_conn
*
ct
=
&
per_cpu
(
nf_conntrack_untracked
,
cpu
);
cnt
+=
atomic_read
(
&
ct
->
ct_general
.
use
)
-
1
;
}
return
cnt
;
}
static
void
nf_conntrack_cleanup_init_net
(
void
)
{
/* wait until all references to nf_conntrack_untracked are dropped */
while
(
atomic_read
(
&
nf_conntrack_untracked
.
ct_general
.
use
)
>
1
)
while
(
untrack_refs
()
>
0
)
schedule
();
nf_conntrack_helper_fini
();
...
...
@@ -1319,10 +1330,19 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
module_param_call
(
hashsize
,
nf_conntrack_set_hashsize
,
param_get_uint
,
&
nf_conntrack_htable_size
,
0600
);
void
nf_ct_untracked_status_or
(
unsigned
long
bits
)
{
int
cpu
;
for_each_possible_cpu
(
cpu
)
per_cpu
(
nf_conntrack_untracked
,
cpu
).
status
|=
bits
;
}
EXPORT_SYMBOL_GPL
(
nf_ct_untracked_status_or
);
static
int
nf_conntrack_init_init_net
(
void
)
{
int
max_factor
=
8
;
int
ret
;
int
ret
,
cpu
;
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
* machine has 512 buckets. >= 1GB machines have 16384 buckets. */
...
...
@@ -1361,11 +1381,13 @@ static int nf_conntrack_init_init_net(void)
goto
err_extend
;
#endif
/* Set up fake conntrack: to never be deleted, not in any hashes */
write_pnet
(
&
nf_conntrack_untracked
.
ct_net
,
&
init_net
);
atomic_set
(
&
nf_conntrack_untracked
.
ct_general
.
use
,
1
);
for_each_possible_cpu
(
cpu
)
{
struct
nf_conn
*
ct
=
&
per_cpu
(
nf_conntrack_untracked
,
cpu
);
write_pnet
(
&
ct
->
ct_net
,
&
init_net
);
atomic_set
(
&
ct
->
ct_general
.
use
,
1
);
}
/* - and look it like as a confirmed connection */
set_bit
(
IPS_CONFIRMED_BIT
,
&
nf_conntrack_untracked
.
status
);
nf_ct_untracked_status_or
(
IPS_CONFIRMED
|
IPS_UNTRACKED
);
return
0
;
#ifdef CONFIG_NF_CONNTRACK_ZONES
...
...
net/netfilter/nf_conntrack_netlink.c
浏览文件 @
16fb62b6
...
...
@@ -480,7 +480,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
int
err
;
/* ignore our fake conntrack entry */
if
(
ct
==
&
nf_conntrack_untracked
)
if
(
nf_ct_is_untracked
(
ct
)
)
return
0
;
if
(
events
&
(
1
<<
IPCT_DESTROY
))
{
...
...
net/netfilter/nfnetlink_log.c
浏览文件 @
16fb62b6
...
...
@@ -66,9 +66,10 @@ struct nfulnl_instance {
u_int16_t
group_num
;
/* number of this queue */
u_int16_t
flags
;
u_int8_t
copy_mode
;
struct
rcu_head
rcu
;
};
static
DEFINE_
RW
LOCK
(
instances_lock
);
static
DEFINE_
SPIN
LOCK
(
instances_lock
);
static
atomic_t
global_seq
;
#define INSTANCE_BUCKETS 16
...
...
@@ -88,7 +89,7 @@ __instance_lookup(u_int16_t group_num)
struct
nfulnl_instance
*
inst
;
head
=
&
instance_table
[
instance_hashfn
(
group_num
)];
hlist_for_each_entry
(
inst
,
pos
,
head
,
hlist
)
{
hlist_for_each_entry
_rcu
(
inst
,
pos
,
head
,
hlist
)
{
if
(
inst
->
group_num
==
group_num
)
return
inst
;
}
...
...
@@ -106,22 +107,26 @@ instance_lookup_get(u_int16_t group_num)
{
struct
nfulnl_instance
*
inst
;
r
ead_lock_bh
(
&
instances_lock
);
r
cu_read_lock_bh
(
);
inst
=
__instance_lookup
(
group_num
);
if
(
inst
)
inst
ance_get
(
inst
)
;
r
ead_unlock_bh
(
&
instances_lock
);
if
(
inst
&&
!
atomic_inc_not_zero
(
&
inst
->
use
)
)
inst
=
NULL
;
r
cu_read_unlock_bh
(
);
return
inst
;
}
static
void
nfulnl_instance_free_rcu
(
struct
rcu_head
*
head
)
{
kfree
(
container_of
(
head
,
struct
nfulnl_instance
,
rcu
));
module_put
(
THIS_MODULE
);
}
static
void
instance_put
(
struct
nfulnl_instance
*
inst
)
{
if
(
inst
&&
atomic_dec_and_test
(
&
inst
->
use
))
{
kfree
(
inst
);
module_put
(
THIS_MODULE
);
}
if
(
inst
&&
atomic_dec_and_test
(
&
inst
->
use
))
call_rcu_bh
(
&
inst
->
rcu
,
nfulnl_instance_free_rcu
);
}
static
void
nfulnl_timer
(
unsigned
long
data
);
...
...
@@ -132,7 +137,7 @@ instance_create(u_int16_t group_num, int pid)
struct
nfulnl_instance
*
inst
;
int
err
;
write
_lock_bh
(
&
instances_lock
);
spin
_lock_bh
(
&
instances_lock
);
if
(
__instance_lookup
(
group_num
))
{
err
=
-
EEXIST
;
goto
out_unlock
;
...
...
@@ -166,32 +171,37 @@ instance_create(u_int16_t group_num, int pid)
inst
->
copy_mode
=
NFULNL_COPY_PACKET
;
inst
->
copy_range
=
NFULNL_COPY_RANGE_MAX
;
hlist_add_head
(
&
inst
->
hlist
,
hlist_add_head
_rcu
(
&
inst
->
hlist
,
&
instance_table
[
instance_hashfn
(
group_num
)]);
write
_unlock_bh
(
&
instances_lock
);
spin
_unlock_bh
(
&
instances_lock
);
return
inst
;
out_unlock:
write
_unlock_bh
(
&
instances_lock
);
spin
_unlock_bh
(
&
instances_lock
);
return
ERR_PTR
(
err
);
}
static
void
__nfulnl_flush
(
struct
nfulnl_instance
*
inst
);
/* called with BH disabled */
static
void
__instance_destroy
(
struct
nfulnl_instance
*
inst
)
{
/* first pull it out of the global list */
hlist_del
(
&
inst
->
hlist
);
hlist_del
_rcu
(
&
inst
->
hlist
);
/* then flush all pending packets from skb */
spin_lock_bh
(
&
inst
->
lock
);
spin_lock
(
&
inst
->
lock
);
/* lockless readers wont be able to use us */
inst
->
copy_mode
=
NFULNL_COPY_DISABLED
;
if
(
inst
->
skb
)
__nfulnl_flush
(
inst
);
spin_unlock
_bh
(
&
inst
->
lock
);
spin_unlock
(
&
inst
->
lock
);
/* and finally put the refcount */
instance_put
(
inst
);
...
...
@@ -200,9 +210,9 @@ __instance_destroy(struct nfulnl_instance *inst)
static
inline
void
instance_destroy
(
struct
nfulnl_instance
*
inst
)
{
write
_lock_bh
(
&
instances_lock
);
spin
_lock_bh
(
&
instances_lock
);
__instance_destroy
(
inst
);
write
_unlock_bh
(
&
instances_lock
);
spin
_unlock_bh
(
&
instances_lock
);
}
static
int
...
...
@@ -621,6 +631,7 @@ nfulnl_log_packet(u_int8_t pf,
size
+=
nla_total_size
(
data_len
);
break
;
case
NFULNL_COPY_DISABLED
:
default:
goto
unlock_and_release
;
}
...
...
@@ -674,7 +685,7 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
int
i
;
/* destroy all instances for this pid */
write
_lock_bh
(
&
instances_lock
);
spin
_lock_bh
(
&
instances_lock
);
for
(
i
=
0
;
i
<
INSTANCE_BUCKETS
;
i
++
)
{
struct
hlist_node
*
tmp
,
*
t2
;
struct
nfulnl_instance
*
inst
;
...
...
@@ -686,7 +697,7 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
__instance_destroy
(
inst
);
}
}
write
_unlock_bh
(
&
instances_lock
);
spin
_unlock_bh
(
&
instances_lock
);
}
return
NOTIFY_DONE
;
}
...
...
@@ -863,19 +874,19 @@ static struct hlist_node *get_first(struct iter_state *st)
for
(
st
->
bucket
=
0
;
st
->
bucket
<
INSTANCE_BUCKETS
;
st
->
bucket
++
)
{
if
(
!
hlist_empty
(
&
instance_table
[
st
->
bucket
]))
return
instance_table
[
st
->
bucket
].
first
;
return
rcu_dereference_bh
(
instance_table
[
st
->
bucket
].
first
)
;
}
return
NULL
;
}
static
struct
hlist_node
*
get_next
(
struct
iter_state
*
st
,
struct
hlist_node
*
h
)
{
h
=
h
->
next
;
h
=
rcu_dereference_bh
(
h
->
next
)
;
while
(
!
h
)
{
if
(
++
st
->
bucket
>=
INSTANCE_BUCKETS
)
return
NULL
;
h
=
instance_table
[
st
->
bucket
].
first
;
h
=
rcu_dereference_bh
(
instance_table
[
st
->
bucket
].
first
)
;
}
return
h
;
}
...
...
@@ -892,9 +903,9 @@ static struct hlist_node *get_idx(struct iter_state *st, loff_t pos)
}
static
void
*
seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
__acquires
(
instances_lock
)
__acquires
(
rcu_bh
)
{
r
ead_lock_bh
(
&
instances_lock
);
r
cu_read_lock_bh
(
);
return
get_idx
(
seq
->
private
,
*
pos
);
}
...
...
@@ -905,9 +916,9 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static
void
seq_stop
(
struct
seq_file
*
s
,
void
*
v
)
__releases
(
instances_lock
)
__releases
(
rcu_bh
)
{
r
ead_unlock_bh
(
&
instances_lock
);
r
cu_read_unlock_bh
(
);
}
static
int
seq_show
(
struct
seq_file
*
s
,
void
*
v
)
...
...
net/netfilter/nfnetlink_queue.c
浏览文件 @
16fb62b6
...
...
@@ -46,17 +46,19 @@ struct nfqnl_instance {
int
peer_pid
;
unsigned
int
queue_maxlen
;
unsigned
int
copy_range
;
unsigned
int
queue_total
;
unsigned
int
queue_dropped
;
unsigned
int
queue_user_dropped
;
unsigned
int
id_sequence
;
/* 'sequence' of pkt ids */
u_int16_t
queue_num
;
/* number of this queue */
u_int8_t
copy_mode
;
spinlock_t
lock
;
/*
* Following fields are dirtied for each queued packet,
* keep them in same cache line if possible.
*/
spinlock_t
lock
;
unsigned
int
queue_total
;
atomic_t
id_sequence
;
/* 'sequence' of pkt ids */
struct
list_head
queue_list
;
/* packets in queue */
};
...
...
@@ -238,32 +240,24 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
outdev
=
entry
->
outdev
;
spin_lock_bh
(
&
queue
->
lock
);
switch
((
enum
nfqnl_config_mode
)
queue
->
copy_mode
)
{
switch
((
enum
nfqnl_config_mode
)
ACCESS_ONCE
(
queue
->
copy_mode
))
{
case
NFQNL_COPY_META
:
case
NFQNL_COPY_NONE
:
break
;
case
NFQNL_COPY_PACKET
:
if
(
entskb
->
ip_summed
==
CHECKSUM_PARTIAL
&&
skb_checksum_help
(
entskb
))
{
spin_unlock_bh
(
&
queue
->
lock
);
skb_checksum_help
(
entskb
))
return
NULL
;
}
if
(
queue
->
copy_range
==
0
||
queue
->
copy_range
>
entskb
->
len
)
data_len
=
ACCESS_ONCE
(
queue
->
copy_range
);
if
(
data_len
==
0
||
data_len
>
entskb
->
len
)
data_len
=
entskb
->
len
;
else
data_len
=
queue
->
copy_range
;
size
+=
nla_total_size
(
data_len
);
break
;
}
entry
->
id
=
queue
->
id_sequence
++
;
spin_unlock_bh
(
&
queue
->
lock
);
skb
=
alloc_skb
(
size
,
GFP_ATOMIC
);
if
(
!
skb
)
...
...
@@ -278,6 +272,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
nfmsg
->
version
=
NFNETLINK_V0
;
nfmsg
->
res_id
=
htons
(
queue
->
queue_num
);
entry
->
id
=
atomic_inc_return
(
&
queue
->
id_sequence
);
pmsg
.
packet_id
=
htonl
(
entry
->
id
);
pmsg
.
hw_protocol
=
entskb
->
protocol
;
pmsg
.
hook
=
entry
->
hook
;
...
...
@@ -868,7 +863,7 @@ static int seq_show(struct seq_file *s, void *v)
inst
->
peer_pid
,
inst
->
queue_total
,
inst
->
copy_mode
,
inst
->
copy_range
,
inst
->
queue_dropped
,
inst
->
queue_user_dropped
,
inst
->
id_sequence
,
1
);
atomic_read
(
&
inst
->
id_sequence
)
,
1
);
}
static
const
struct
seq_operations
nfqnl_seq_ops
=
{
...
...
net/netfilter/xt_CT.c
浏览文件 @
16fb62b6
...
...
@@ -67,7 +67,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par)
return
-
EINVAL
;
if
(
info
->
flags
&
XT_CT_NOTRACK
)
{
ct
=
&
nf_conntrack_untracked
;
ct
=
nf_ct_untracked_get
()
;
atomic_inc
(
&
ct
->
ct_general
.
use
);
goto
out
;
}
...
...
@@ -132,7 +132,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par)
struct
nf_conn
*
ct
=
info
->
ct
;
struct
nf_conn_help
*
help
;
if
(
ct
!=
&
nf_conntrack_untracked
)
{
if
(
!
nf_ct_is_untracked
(
ct
)
)
{
help
=
nfct_help
(
ct
);
if
(
help
)
module_put
(
help
->
helper
->
me
);
...
...
net/netfilter/xt_IDLETIMER.c
0 → 100644
浏览文件 @
16fb62b6
/*
* linux/net/netfilter/xt_IDLETIMER.c
*
* Netfilter module to trigger a timer when packet matches.
* After timer expires a kevent will be sent.
*
* Copyright (C) 2004, 2010 Nokia Corporation
* Written by Timo Teras <ext-timo.teras@nokia.com>
*
* Converted to x_tables and reworked for upstream inclusion
* by Luciano Coelho <luciano.coelho@nokia.com>
*
* Contact: Luciano Coelho <luciano.coelho@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_IDLETIMER.h>
#include <linux/kobject.h>
#include <linux/workqueue.h>
#include <linux/sysfs.h>
struct
idletimer_tg_attr
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
);
};
struct
idletimer_tg
{
struct
list_head
entry
;
struct
timer_list
timer
;
struct
work_struct
work
;
struct
kobject
*
kobj
;
struct
idletimer_tg_attr
attr
;
unsigned
int
refcnt
;
};
static
LIST_HEAD
(
idletimer_tg_list
);
static
DEFINE_MUTEX
(
list_mutex
);
static
struct
kobject
*
idletimer_tg_kobj
;
static
struct
idletimer_tg
*
__idletimer_tg_find_by_label
(
const
char
*
label
)
{
struct
idletimer_tg
*
entry
;
BUG_ON
(
!
label
);
list_for_each_entry
(
entry
,
&
idletimer_tg_list
,
entry
)
{
if
(
!
strcmp
(
label
,
entry
->
attr
.
attr
.
name
))
return
entry
;
}
return
NULL
;
}
static
ssize_t
idletimer_tg_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
idletimer_tg
*
timer
;
unsigned
long
expires
=
0
;
mutex_lock
(
&
list_mutex
);
timer
=
__idletimer_tg_find_by_label
(
attr
->
name
);
if
(
timer
)
expires
=
timer
->
timer
.
expires
;
mutex_unlock
(
&
list_mutex
);
if
(
time_after
(
expires
,
jiffies
))
return
sprintf
(
buf
,
"%u
\n
"
,
jiffies_to_msecs
(
expires
-
jiffies
)
/
1000
);
return
sprintf
(
buf
,
"0
\n
"
);
}
static
void
idletimer_tg_work
(
struct
work_struct
*
work
)
{
struct
idletimer_tg
*
timer
=
container_of
(
work
,
struct
idletimer_tg
,
work
);
sysfs_notify
(
idletimer_tg_kobj
,
NULL
,
timer
->
attr
.
attr
.
name
);
}
static
void
idletimer_tg_expired
(
unsigned
long
data
)
{
struct
idletimer_tg
*
timer
=
(
struct
idletimer_tg
*
)
data
;
pr_debug
(
"timer %s expired
\n
"
,
timer
->
attr
.
attr
.
name
);
schedule_work
(
&
timer
->
work
);
}
static
int
idletimer_tg_create
(
struct
idletimer_tg_info
*
info
)
{
int
ret
;
info
->
timer
=
kmalloc
(
sizeof
(
*
info
->
timer
),
GFP_KERNEL
);
if
(
!
info
->
timer
)
{
pr_debug
(
"couldn't alloc timer
\n
"
);
ret
=
-
ENOMEM
;
goto
out
;
}
info
->
timer
->
attr
.
attr
.
name
=
kstrdup
(
info
->
label
,
GFP_KERNEL
);
if
(
!
info
->
timer
->
attr
.
attr
.
name
)
{
pr_debug
(
"couldn't alloc attribute name
\n
"
);
ret
=
-
ENOMEM
;
goto
out_free_timer
;
}
info
->
timer
->
attr
.
attr
.
mode
=
S_IRUGO
;
info
->
timer
->
attr
.
show
=
idletimer_tg_show
;
ret
=
sysfs_create_file
(
idletimer_tg_kobj
,
&
info
->
timer
->
attr
.
attr
);
if
(
ret
<
0
)
{
pr_debug
(
"couldn't add file to sysfs"
);
goto
out_free_attr
;
}
list_add
(
&
info
->
timer
->
entry
,
&
idletimer_tg_list
);
setup_timer
(
&
info
->
timer
->
timer
,
idletimer_tg_expired
,
(
unsigned
long
)
info
->
timer
);
info
->
timer
->
refcnt
=
1
;
mod_timer
(
&
info
->
timer
->
timer
,
msecs_to_jiffies
(
info
->
timeout
*
1000
)
+
jiffies
);
INIT_WORK
(
&
info
->
timer
->
work
,
idletimer_tg_work
);
return
0
;
out_free_attr:
kfree
(
info
->
timer
->
attr
.
attr
.
name
);
out_free_timer:
kfree
(
info
->
timer
);
out:
return
ret
;
}
/*
* The actual xt_tables plugin.
*/
static
unsigned
int
idletimer_tg_target
(
struct
sk_buff
*
skb
,
const
struct
xt_action_param
*
par
)
{
const
struct
idletimer_tg_info
*
info
=
par
->
targinfo
;
pr_debug
(
"resetting timer %s, timeout period %u
\n
"
,
info
->
label
,
info
->
timeout
);
BUG_ON
(
!
info
->
timer
);
mod_timer
(
&
info
->
timer
->
timer
,
msecs_to_jiffies
(
info
->
timeout
*
1000
)
+
jiffies
);
return
XT_CONTINUE
;
}
static
int
idletimer_tg_checkentry
(
const
struct
xt_tgchk_param
*
par
)
{
struct
idletimer_tg_info
*
info
=
par
->
targinfo
;
int
ret
;
pr_debug
(
"checkentry targinfo%s
\n
"
,
info
->
label
);
if
(
info
->
timeout
==
0
)
{
pr_debug
(
"timeout value is zero
\n
"
);
return
-
EINVAL
;
}
if
(
info
->
label
[
0
]
==
'\0'
||
strnlen
(
info
->
label
,
MAX_IDLETIMER_LABEL_SIZE
)
==
MAX_IDLETIMER_LABEL_SIZE
)
{
pr_debug
(
"label is empty or not nul-terminated
\n
"
);
return
-
EINVAL
;
}
mutex_lock
(
&
list_mutex
);
info
->
timer
=
__idletimer_tg_find_by_label
(
info
->
label
);
if
(
info
->
timer
)
{
info
->
timer
->
refcnt
++
;
mod_timer
(
&
info
->
timer
->
timer
,
msecs_to_jiffies
(
info
->
timeout
*
1000
)
+
jiffies
);
pr_debug
(
"increased refcnt of timer %s to %u
\n
"
,
info
->
label
,
info
->
timer
->
refcnt
);
}
else
{
ret
=
idletimer_tg_create
(
info
);
if
(
ret
<
0
)
{
pr_debug
(
"failed to create timer
\n
"
);
mutex_unlock
(
&
list_mutex
);
return
ret
;
}
}
mutex_unlock
(
&
list_mutex
);
return
0
;
}
static
void
idletimer_tg_destroy
(
const
struct
xt_tgdtor_param
*
par
)
{
const
struct
idletimer_tg_info
*
info
=
par
->
targinfo
;
pr_debug
(
"destroy targinfo %s
\n
"
,
info
->
label
);
mutex_lock
(
&
list_mutex
);
if
(
--
info
->
timer
->
refcnt
==
0
)
{
pr_debug
(
"deleting timer %s
\n
"
,
info
->
label
);
list_del
(
&
info
->
timer
->
entry
);
del_timer_sync
(
&
info
->
timer
->
timer
);
sysfs_remove_file
(
idletimer_tg_kobj
,
&
info
->
timer
->
attr
.
attr
);
kfree
(
info
->
timer
->
attr
.
attr
.
name
);
kfree
(
info
->
timer
);
}
else
{
pr_debug
(
"decreased refcnt of timer %s to %u
\n
"
,
info
->
label
,
info
->
timer
->
refcnt
);
}
mutex_unlock
(
&
list_mutex
);
}
static
struct
xt_target
idletimer_tg
__read_mostly
=
{
.
name
=
"IDLETIMER"
,
.
family
=
NFPROTO_UNSPEC
,
.
target
=
idletimer_tg_target
,
.
targetsize
=
sizeof
(
struct
idletimer_tg_info
),
.
checkentry
=
idletimer_tg_checkentry
,
.
destroy
=
idletimer_tg_destroy
,
.
me
=
THIS_MODULE
,
};
static
struct
class
*
idletimer_tg_class
;
static
struct
device
*
idletimer_tg_device
;
static
int
__init
idletimer_tg_init
(
void
)
{
int
err
;
idletimer_tg_class
=
class_create
(
THIS_MODULE
,
"xt_idletimer"
);
err
=
PTR_ERR
(
idletimer_tg_class
);
if
(
IS_ERR
(
idletimer_tg_class
))
{
pr_debug
(
"couldn't register device class
\n
"
);
goto
out
;
}
idletimer_tg_device
=
device_create
(
idletimer_tg_class
,
NULL
,
MKDEV
(
0
,
0
),
NULL
,
"timers"
);
err
=
PTR_ERR
(
idletimer_tg_device
);
if
(
IS_ERR
(
idletimer_tg_device
))
{
pr_debug
(
"couldn't register system device
\n
"
);
goto
out_class
;
}
idletimer_tg_kobj
=
&
idletimer_tg_device
->
kobj
;
err
=
xt_register_target
(
&
idletimer_tg
);
if
(
err
<
0
)
{
pr_debug
(
"couldn't register xt target
\n
"
);
goto
out_dev
;
}
return
0
;
out_dev:
device_destroy
(
idletimer_tg_class
,
MKDEV
(
0
,
0
));
out_class:
class_destroy
(
idletimer_tg_class
);
out:
return
err
;
}
static
void
__exit
idletimer_tg_exit
(
void
)
{
xt_unregister_target
(
&
idletimer_tg
);
device_destroy
(
idletimer_tg_class
,
MKDEV
(
0
,
0
));
class_destroy
(
idletimer_tg_class
);
}
module_init
(
idletimer_tg_init
);
module_exit
(
idletimer_tg_exit
);
MODULE_AUTHOR
(
"Timo Teras <ext-timo.teras@nokia.com>"
);
MODULE_AUTHOR
(
"Luciano Coelho <luciano.coelho@nokia.com>"
);
MODULE_DESCRIPTION
(
"Xtables: idle time monitor"
);
MODULE_LICENSE
(
"GPL v2"
);
net/netfilter/xt_NOTRACK.c
浏览文件 @
16fb62b6
...
...
@@ -23,7 +23,7 @@ notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */
skb
->
nfct
=
&
nf_c
onntrack_untracked
.
ct_general
;
skb
->
nfct
=
&
nf_c
t_untracked_get
()
->
ct_general
;
skb
->
nfctinfo
=
IP_CT_NEW
;
nf_conntrack_get
(
skb
->
nfct
);
...
...
net/netfilter/xt_TEE.c
浏览文件 @
16fb62b6
...
...
@@ -104,7 +104,7 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
#ifdef WITH_CONNTRACK
/* Avoid counting cloned packets towards the original connection. */
nf_conntrack_put
(
skb
->
nfct
);
skb
->
nfct
=
&
nf_c
onntrack_untracked
.
ct_general
;
skb
->
nfct
=
&
nf_c
t_untracked_get
()
->
ct_general
;
skb
->
nfctinfo
=
IP_CT_NEW
;
nf_conntrack_get
(
skb
->
nfct
);
#endif
...
...
@@ -177,7 +177,7 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
#ifdef WITH_CONNTRACK
nf_conntrack_put
(
skb
->
nfct
);
skb
->
nfct
=
&
nf_c
onntrack_untracked
.
ct_general
;
skb
->
nfct
=
&
nf_c
t_untracked_get
()
->
ct_general
;
skb
->
nfctinfo
=
IP_CT_NEW
;
nf_conntrack_get
(
skb
->
nfct
);
#endif
...
...
net/netfilter/xt_cluster.c
浏览文件 @
16fb62b6
...
...
@@ -120,7 +120,7 @@ xt_cluster_mt(const struct sk_buff *skb, struct xt_action_param *par)
if
(
ct
==
NULL
)
return
false
;
if
(
ct
==
&
nf_conntrack_untracked
)
if
(
nf_ct_is_untracked
(
ct
)
)
return
false
;
if
(
ct
->
master
)
...
...
net/netfilter/xt_conntrack.c
浏览文件 @
16fb62b6
...
...
@@ -123,11 +123,12 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
ct
=
nf_ct_get
(
skb
,
&
ctinfo
);
if
(
ct
==
&
nf_conntrack_untracked
)
statebit
=
XT_CONNTRACK_STATE_UNTRACKED
;
else
if
(
ct
!=
NULL
)
statebit
=
XT_CONNTRACK_STATE_BIT
(
ctinfo
);
else
if
(
ct
)
{
if
(
nf_ct_is_untracked
(
ct
))
statebit
=
XT_CONNTRACK_STATE_UNTRACKED
;
else
statebit
=
XT_CONNTRACK_STATE_BIT
(
ctinfo
);
}
else
statebit
=
XT_CONNTRACK_STATE_INVALID
;
if
(
info
->
match_flags
&
XT_CONNTRACK_STATE
)
{
...
...
net/netfilter/xt_sctp.c
浏览文件 @
16fb62b6
...
...
@@ -3,6 +3,7 @@
#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/sctp/sctp.h>
#include <linux/sctp.h>
#include <linux/netfilter/x_tables.h>
...
...
@@ -67,7 +68,7 @@ match_packet(const struct sk_buff *skb,
++
i
,
offset
,
sch
->
type
,
htons
(
sch
->
length
),
sch
->
flags
);
#endif
offset
+=
(
ntohs
(
sch
->
length
)
+
3
)
&
~
3
;
offset
+=
WORD_ROUND
(
ntohs
(
sch
->
length
))
;
pr_debug
(
"skb->len: %d
\t
offset: %d
\n
"
,
skb
->
len
,
offset
);
...
...
net/netfilter/xt_socket.c
浏览文件 @
16fb62b6
...
...
@@ -127,7 +127,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
* reply packet of an established SNAT-ted connection. */
ct
=
nf_ct_get
(
skb
,
&
ctinfo
);
if
(
ct
&&
(
ct
!=
&
nf_conntrack_untracked
)
&&
if
(
ct
&&
!
nf_ct_is_untracked
(
ct
)
&&
((
iph
->
protocol
!=
IPPROTO_ICMP
&&
ctinfo
==
IP_CT_IS_REPLY
+
IP_CT_ESTABLISHED
)
||
(
iph
->
protocol
==
IPPROTO_ICMP
&&
...
...
net/netfilter/xt_state.c
浏览文件 @
16fb62b6
...
...
@@ -26,14 +26,16 @@ state_mt(const struct sk_buff *skb, struct xt_action_param *par)
const
struct
xt_state_info
*
sinfo
=
par
->
matchinfo
;
enum
ip_conntrack_info
ctinfo
;
unsigned
int
statebit
;
struct
nf_conn
*
ct
=
nf_ct_get
(
skb
,
&
ctinfo
);
if
(
nf_ct_is_untracked
(
skb
))
statebit
=
XT_STATE_UNTRACKED
;
else
if
(
!
nf_ct_get
(
skb
,
&
ctinfo
))
if
(
!
ct
)
statebit
=
XT_STATE_INVALID
;
else
statebit
=
XT_STATE_BIT
(
ctinfo
);
else
{
if
(
nf_ct_is_untracked
(
ct
))
statebit
=
XT_STATE_UNTRACKED
;
else
statebit
=
XT_STATE_BIT
(
ctinfo
);
}
return
(
sinfo
->
statemask
&
statebit
);
}
...
...
net/netfilter/xt_statistic.c
浏览文件 @
16fb62b6
...
...
@@ -18,8 +18,8 @@
#include <linux/netfilter/x_tables.h>
struct
xt_statistic_priv
{
uint32
_t
count
;
};
atomic
_t
count
;
}
____cacheline_aligned_in_smp
;
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Patrick McHardy <kaber@trash.net>"
);
...
...
@@ -27,13 +27,12 @@ MODULE_DESCRIPTION("Xtables: statistics-based matching (\"Nth\", random)");
MODULE_ALIAS
(
"ipt_statistic"
);
MODULE_ALIAS
(
"ip6t_statistic"
);
static
DEFINE_SPINLOCK
(
nth_lock
);
static
bool
statistic_mt
(
const
struct
sk_buff
*
skb
,
struct
xt_action_param
*
par
)
{
const
struct
xt_statistic_info
*
info
=
par
->
matchinfo
;
bool
ret
=
info
->
flags
&
XT_STATISTIC_INVERT
;
int
nval
,
oval
;
switch
(
info
->
mode
)
{
case
XT_STATISTIC_MODE_RANDOM
:
...
...
@@ -41,12 +40,12 @@ statistic_mt(const struct sk_buff *skb, struct xt_action_param *par)
ret
=
!
ret
;
break
;
case
XT_STATISTIC_MODE_NTH
:
spin_lock_bh
(
&
nth_lock
);
if
(
info
->
master
->
count
++
==
info
->
u
.
nth
.
every
)
{
info
->
master
->
count
=
0
;
do
{
oval
=
atomic_read
(
&
info
->
master
->
count
);
nval
=
(
oval
==
info
->
u
.
nth
.
every
)
?
0
:
oval
+
1
;
}
while
(
atomic_cmpxchg
(
&
info
->
master
->
count
,
oval
,
nval
)
!=
oval
);
if
(
nval
==
0
)
ret
=
!
ret
;
}
spin_unlock_bh
(
&
nth_lock
);
break
;
}
...
...
@@ -64,7 +63,7 @@ static int statistic_mt_check(const struct xt_mtchk_param *par)
info
->
master
=
kzalloc
(
sizeof
(
*
info
->
master
),
GFP_KERNEL
);
if
(
info
->
master
==
NULL
)
return
-
ENOMEM
;
info
->
master
->
count
=
info
->
u
.
nth
.
count
;
atomic_set
(
&
info
->
master
->
count
,
info
->
u
.
nth
.
count
)
;
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录