Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8c6b0865
Commit
8c6b0865
authored
Mar 23, 2012
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://1984.lsi.us.es/net
parents
8a783354
60b5f8f7
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
100 additions
and
54 deletions
+100
-54
include/net/netfilter/nf_conntrack_l4proto.h
include/net/netfilter/nf_conntrack_l4proto.h
+4
-0
include/net/netfilter/nf_conntrack_timeout.h
include/net/netfilter/nf_conntrack_timeout.h
+1
-1
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_core.c
+22
-17
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_conntrack_proto.c
+21
-0
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nfnetlink_cttimeout.c
+23
-22
net/netfilter/xt_CT.c
net/netfilter/xt_CT.c
+23
-8
net/netfilter/xt_LOG.c
net/netfilter/xt_LOG.c
+6
-6
No files found.
include/net/netfilter/nf_conntrack_l4proto.h
View file @
8c6b0865
...
...
@@ -118,6 +118,10 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
extern
struct
nf_conntrack_l4proto
*
__nf_ct_l4proto_find
(
u_int16_t
l3proto
,
u_int8_t
l4proto
);
extern
struct
nf_conntrack_l4proto
*
nf_ct_l4proto_find_get
(
u_int16_t
l3proto
,
u_int8_t
l4proto
);
extern
void
nf_ct_l4proto_put
(
struct
nf_conntrack_l4proto
*
p
);
/* Protocol registration. */
extern
int
nf_conntrack_l4proto_register
(
struct
nf_conntrack_l4proto
*
proto
);
extern
void
nf_conntrack_l4proto_unregister
(
struct
nf_conntrack_l4proto
*
proto
);
...
...
include/net/netfilter/nf_conntrack_timeout.h
View file @
8c6b0865
...
...
@@ -15,7 +15,7 @@ struct ctnl_timeout {
atomic_t
refcnt
;
char
name
[
CTNL_TIMEOUT_NAME_MAX
];
__u16
l3num
;
__u8
l4num
;
struct
nf_conntrack_l4proto
*
l4proto
;
char
data
[
0
];
};
...
...
net/netfilter/nf_conntrack_core.c
View file @
8c6b0865
...
...
@@ -768,8 +768,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
struct
nf_conntrack_l3proto
*
l3proto
,
struct
nf_conntrack_l4proto
*
l4proto
,
struct
sk_buff
*
skb
,
unsigned
int
dataoff
,
u32
hash
,
unsigned
int
*
timeouts
)
unsigned
int
dataoff
,
u32
hash
)
{
struct
nf_conn
*
ct
;
struct
nf_conn_help
*
help
;
...
...
@@ -777,6 +776,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
struct
nf_conntrack_ecache
*
ecache
;
struct
nf_conntrack_expect
*
exp
;
u16
zone
=
tmpl
?
nf_ct_zone
(
tmpl
)
:
NF_CT_DEFAULT_ZONE
;
struct
nf_conn_timeout
*
timeout_ext
;
unsigned
int
*
timeouts
;
if
(
!
nf_ct_invert_tuple
(
&
repl_tuple
,
tuple
,
l3proto
,
l4proto
))
{
pr_debug
(
"Can't invert tuple.
\n
"
);
...
...
@@ -788,12 +789,21 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
if
(
IS_ERR
(
ct
))
return
(
struct
nf_conntrack_tuple_hash
*
)
ct
;
timeout_ext
=
tmpl
?
nf_ct_timeout_find
(
tmpl
)
:
NULL
;
if
(
timeout_ext
)
timeouts
=
NF_CT_TIMEOUT_EXT_DATA
(
timeout_ext
);
else
timeouts
=
l4proto
->
get_timeouts
(
net
);
if
(
!
l4proto
->
new
(
ct
,
skb
,
dataoff
,
timeouts
))
{
nf_conntrack_free
(
ct
);
pr_debug
(
"init conntrack: can't track with proto module
\n
"
);
return
NULL
;
}
if
(
timeout_ext
)
nf_ct_timeout_ext_add
(
ct
,
timeout_ext
->
timeout
,
GFP_ATOMIC
);
nf_ct_acct_ext_add
(
ct
,
GFP_ATOMIC
);
nf_ct_tstamp_ext_add
(
ct
,
GFP_ATOMIC
);
...
...
@@ -854,8 +864,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
struct
nf_conntrack_l3proto
*
l3proto
,
struct
nf_conntrack_l4proto
*
l4proto
,
int
*
set_reply
,
enum
ip_conntrack_info
*
ctinfo
,
unsigned
int
*
timeouts
)
enum
ip_conntrack_info
*
ctinfo
)
{
struct
nf_conntrack_tuple
tuple
;
struct
nf_conntrack_tuple_hash
*
h
;
...
...
@@ -875,7 +884,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
h
=
__nf_conntrack_find_get
(
net
,
zone
,
&
tuple
,
hash
);
if
(
!
h
)
{
h
=
init_conntrack
(
net
,
tmpl
,
&
tuple
,
l3proto
,
l4proto
,
skb
,
dataoff
,
hash
,
timeouts
);
skb
,
dataoff
,
hash
);
if
(
!
h
)
return
NULL
;
if
(
IS_ERR
(
h
))
...
...
@@ -964,19 +973,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
goto
out
;
}
/* Decide what timeout policy we want to apply to this flow. */
if
(
tmpl
)
{
timeout_ext
=
nf_ct_timeout_find
(
tmpl
);
if
(
timeout_ext
)
timeouts
=
NF_CT_TIMEOUT_EXT_DATA
(
timeout_ext
);
else
timeouts
=
l4proto
->
get_timeouts
(
net
);
}
else
timeouts
=
l4proto
->
get_timeouts
(
net
);
ct
=
resolve_normal_ct
(
net
,
tmpl
,
skb
,
dataoff
,
pf
,
protonum
,
l3proto
,
l4proto
,
&
set_reply
,
&
ctinfo
,
timeouts
);
l3proto
,
l4proto
,
&
set_reply
,
&
ctinfo
);
if
(
!
ct
)
{
/* Not valid part of a connection */
NF_CT_STAT_INC_ATOMIC
(
net
,
invalid
);
...
...
@@ -993,6 +991,13 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
NF_CT_ASSERT
(
skb
->
nfct
);
/* Decide what timeout policy we want to apply to this flow. */
timeout_ext
=
nf_ct_timeout_find
(
ct
);
if
(
timeout_ext
)
timeouts
=
NF_CT_TIMEOUT_EXT_DATA
(
timeout_ext
);
else
timeouts
=
l4proto
->
get_timeouts
(
net
);
ret
=
l4proto
->
packet
(
ct
,
skb
,
dataoff
,
ctinfo
,
pf
,
hooknum
,
timeouts
);
if
(
ret
<=
0
)
{
/* Invalid: inverse of the return code tells
...
...
net/netfilter/nf_conntrack_proto.c
View file @
8c6b0865
...
...
@@ -127,6 +127,27 @@ void nf_ct_l3proto_module_put(unsigned short l3proto)
}
EXPORT_SYMBOL_GPL
(
nf_ct_l3proto_module_put
);
struct
nf_conntrack_l4proto
*
nf_ct_l4proto_find_get
(
u_int16_t
l3num
,
u_int8_t
l4num
)
{
struct
nf_conntrack_l4proto
*
p
;
rcu_read_lock
();
p
=
__nf_ct_l4proto_find
(
l3num
,
l4num
);
if
(
!
try_module_get
(
p
->
me
))
p
=
&
nf_conntrack_l4proto_generic
;
rcu_read_unlock
();
return
p
;
}
EXPORT_SYMBOL_GPL
(
nf_ct_l4proto_find_get
);
void
nf_ct_l4proto_put
(
struct
nf_conntrack_l4proto
*
p
)
{
module_put
(
p
->
me
);
}
EXPORT_SYMBOL_GPL
(
nf_ct_l4proto_put
);
static
int
kill_l3proto
(
struct
nf_conn
*
i
,
void
*
data
)
{
return
nf_ct_l3num
(
i
)
==
((
struct
nf_conntrack_l3proto
*
)
data
)
->
l3proto
;
...
...
net/netfilter/nfnetlink_cttimeout.c
View file @
8c6b0865
...
...
@@ -98,11 +98,13 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
break
;
}
l4proto
=
__nf_ct_l4proto_find
(
l3num
,
l4num
);
l4proto
=
nf_ct_l4proto_find_get
(
l3num
,
l4num
);
/* This protocol is not supportted, skip. */
if
(
l4proto
->
l4proto
!=
l4num
)
return
-
EOPNOTSUPP
;
if
(
l4proto
->
l4proto
!=
l4num
)
{
ret
=
-
EOPNOTSUPP
;
goto
err_proto_put
;
}
if
(
matching
)
{
if
(
nlh
->
nlmsg_flags
&
NLM_F_REPLACE
)
{
...
...
@@ -110,20 +112,25 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
* different kind, sorry.
*/
if
(
matching
->
l3num
!=
l3num
||
matching
->
l4num
!=
l4num
)
return
-
EINVAL
;
matching
->
l4proto
->
l4proto
!=
l4num
)
{
ret
=
-
EINVAL
;
goto
err_proto_put
;
}
ret
=
ctnl_timeout_parse_policy
(
matching
,
l4proto
,
cda
[
CTA_TIMEOUT_DATA
]);
return
ret
;
}
return
-
EBUSY
;
ret
=
-
EBUSY
;
goto
err_proto_put
;
}
timeout
=
kzalloc
(
sizeof
(
struct
ctnl_timeout
)
+
l4proto
->
ctnl_timeout
.
obj_size
,
GFP_KERNEL
);
if
(
timeout
==
NULL
)
return
-
ENOMEM
;
if
(
timeout
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
err_proto_put
;
}
ret
=
ctnl_timeout_parse_policy
(
timeout
,
l4proto
,
cda
[
CTA_TIMEOUT_DATA
]);
...
...
@@ -132,13 +139,15 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
strcpy
(
timeout
->
name
,
nla_data
(
cda
[
CTA_TIMEOUT_NAME
]));
timeout
->
l3num
=
l3num
;
timeout
->
l4
num
=
l4num
;
timeout
->
l4
proto
=
l4proto
;
atomic_set
(
&
timeout
->
refcnt
,
1
);
list_add_tail_rcu
(
&
timeout
->
head
,
&
cttimeout_list
);
return
0
;
err:
kfree
(
timeout
);
err_proto_put:
nf_ct_l4proto_put
(
l4proto
);
return
ret
;
}
...
...
@@ -149,7 +158,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
struct
nlmsghdr
*
nlh
;
struct
nfgenmsg
*
nfmsg
;
unsigned
int
flags
=
pid
?
NLM_F_MULTI
:
0
;
struct
nf_conntrack_l4proto
*
l4proto
;
struct
nf_conntrack_l4proto
*
l4proto
=
timeout
->
l4proto
;
event
|=
NFNL_SUBSYS_CTNETLINK_TIMEOUT
<<
8
;
nlh
=
nlmsg_put
(
skb
,
pid
,
seq
,
event
,
sizeof
(
*
nfmsg
),
flags
);
...
...
@@ -163,20 +172,10 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
NLA_PUT_STRING
(
skb
,
CTA_TIMEOUT_NAME
,
timeout
->
name
);
NLA_PUT_BE16
(
skb
,
CTA_TIMEOUT_L3PROTO
,
htons
(
timeout
->
l3num
));
NLA_PUT_U8
(
skb
,
CTA_TIMEOUT_L4PROTO
,
timeout
->
l4
num
);
NLA_PUT_U8
(
skb
,
CTA_TIMEOUT_L4PROTO
,
timeout
->
l4
proto
->
l4proto
);
NLA_PUT_BE32
(
skb
,
CTA_TIMEOUT_USE
,
htonl
(
atomic_read
(
&
timeout
->
refcnt
)));
l4proto
=
__nf_ct_l4proto_find
(
timeout
->
l3num
,
timeout
->
l4num
);
/* If the timeout object does not match the layer 4 protocol tracker,
* then skip dumping the data part since we don't know how to
* interpret it. This may happen for UPDlite, SCTP and DCCP since
* you can unload the module.
*/
if
(
timeout
->
l4num
!=
l4proto
->
l4proto
)
goto
out
;
if
(
likely
(
l4proto
->
ctnl_timeout
.
obj_to_nlattr
))
{
struct
nlattr
*
nest_parms
;
int
ret
;
...
...
@@ -192,7 +191,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
nla_nest_end
(
skb
,
nest_parms
);
}
out:
nlmsg_end
(
skb
,
nlh
);
return
skb
->
len
;
...
...
@@ -293,6 +292,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
if
(
atomic_dec_and_test
(
&
timeout
->
refcnt
))
{
/* We are protected by nfnl mutex. */
list_del_rcu
(
&
timeout
->
head
);
nf_ct_l4proto_put
(
timeout
->
l4proto
);
kfree_rcu
(
timeout
,
rcu_head
);
}
else
{
/* still in use, restore reference counter. */
...
...
@@ -417,6 +417,7 @@ static void __exit cttimeout_exit(void)
/* We are sure that our objects have no clients at this point,
* it's safe to release them all without checking refcnt.
*/
nf_ct_l4proto_put
(
cur
->
l4proto
);
kfree_rcu
(
cur
,
rcu_head
);
}
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
...
...
net/netfilter/xt_CT.c
View file @
8c6b0865
...
...
@@ -14,8 +14,10 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CT.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_zones.h>
...
...
@@ -217,50 +219,59 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
struct
ctnl_timeout
*
timeout
;
struct
nf_conn_timeout
*
timeout_ext
;
rcu_read_lock
();
timeout_find_get
=
rcu_dereference
(
nf_ct_timeout_find_get_hook
);
if
(
timeout_find_get
)
{
const
struct
ipt_entry
*
e
=
par
->
entryinfo
;
struct
nf_conntrack_l4proto
*
l4proto
;
if
(
e
->
ip
.
invflags
&
IPT_INV_PROTO
)
{
ret
=
-
EINVAL
;
pr_info
(
"You cannot use inversion on "
"L4 protocol
\n
"
);
goto
err
3
;
goto
err
4
;
}
timeout
=
timeout_find_get
(
info
->
timeout
);
if
(
timeout
==
NULL
)
{
ret
=
-
ENOENT
;
pr_info
(
"No such timeout policy
\"
%s
\"\n
"
,
info
->
timeout
);
goto
err
3
;
goto
err
4
;
}
if
(
timeout
->
l3num
!=
par
->
family
)
{
ret
=
-
EINVAL
;
pr_info
(
"Timeout policy `%s' can only be "
"used by L3 protocol number %d
\n
"
,
info
->
timeout
,
timeout
->
l3num
);
goto
err
3
;
goto
err
4
;
}
if
(
timeout
->
l4num
!=
e
->
ip
.
proto
)
{
/* Make sure the timeout policy matches any existing
* protocol tracker, otherwise default to generic.
*/
l4proto
=
__nf_ct_l4proto_find
(
par
->
family
,
e
->
ip
.
proto
);
if
(
timeout
->
l4proto
->
l4proto
!=
l4proto
->
l4proto
)
{
ret
=
-
EINVAL
;
pr_info
(
"Timeout policy `%s' can only be "
"used by L4 protocol number %d
\n
"
,
info
->
timeout
,
timeout
->
l4num
);
goto
err3
;
info
->
timeout
,
timeout
->
l4proto
->
l4proto
);
goto
err4
;
}
timeout_ext
=
nf_ct_timeout_ext_add
(
ct
,
timeout
,
GFP_KERNEL
);
if
(
timeout_ext
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
err
3
;
goto
err
4
;
}
}
else
{
ret
=
-
ENOENT
;
pr_info
(
"Timeout policy base is empty
\n
"
);
goto
err
3
;
goto
err
4
;
}
rcu_read_unlock
();
}
#endif
...
...
@@ -270,6 +281,8 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
info
->
ct
=
ct
;
return
0
;
err4:
rcu_read_unlock
();
err3:
nf_conntrack_free
(
ct
);
err2:
...
...
@@ -311,6 +324,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
nf_ct_l3proto_module_put
(
par
->
family
);
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
rcu_read_lock
();
timeout_put
=
rcu_dereference
(
nf_ct_timeout_put_hook
);
if
(
timeout_put
)
{
...
...
@@ -318,6 +332,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
if
(
timeout_ext
)
timeout_put
(
timeout_ext
->
timeout
);
}
rcu_read_unlock
();
#endif
}
nf_ct_put
(
info
->
ct
);
...
...
net/netfilter/xt_LOG.c
View file @
8c6b0865
...
...
@@ -480,7 +480,7 @@ ipt_log_packet(u_int8_t pf,
sb_close
(
m
);
}
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
/* One level of recursion won't kill us */
static
void
dump_ipv6_packet
(
struct
sbuff
*
m
,
const
struct
nf_loginfo
*
info
,
...
...
@@ -824,7 +824,7 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
if
(
par
->
family
==
NFPROTO_IPV4
)
ipt_log_packet
(
NFPROTO_IPV4
,
par
->
hooknum
,
skb
,
par
->
in
,
par
->
out
,
&
li
,
loginfo
->
prefix
);
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
else
if
(
par
->
family
==
NFPROTO_IPV6
)
ip6t_log_packet
(
NFPROTO_IPV6
,
par
->
hooknum
,
skb
,
par
->
in
,
par
->
out
,
&
li
,
loginfo
->
prefix
);
...
...
@@ -864,7 +864,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
.
checkentry
=
log_tg_check
,
.
me
=
THIS_MODULE
,
},
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
{
.
name
=
"LOG"
,
.
family
=
NFPROTO_IPV6
,
...
...
@@ -882,7 +882,7 @@ static struct nf_logger ipt_log_logger __read_mostly = {
.
me
=
THIS_MODULE
,
};
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
static
struct
nf_logger
ip6t_log_logger
__read_mostly
=
{
.
name
=
"ip6t_LOG"
,
.
logfn
=
&
ip6t_log_packet
,
...
...
@@ -899,7 +899,7 @@ static int __init log_tg_init(void)
return
ret
;
nf_log_register
(
NFPROTO_IPV4
,
&
ipt_log_logger
);
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
nf_log_register
(
NFPROTO_IPV6
,
&
ip6t_log_logger
);
#endif
return
0
;
...
...
@@ -908,7 +908,7 @@ static int __init log_tg_init(void)
static
void
__exit
log_tg_exit
(
void
)
{
nf_log_unregister
(
&
ipt_log_logger
);
#if IS_ENABLED(CONFIG_IP
V6
)
#if IS_ENABLED(CONFIG_IP
6_NF_IPTABLES
)
nf_log_unregister
(
&
ip6t_log_logger
);
#endif
xt_unregister_targets
(
log_tg_regs
,
ARRAY_SIZE
(
log_tg_regs
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment