diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-02-29 02:19:19 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-03-07 17:41:28 +0100 |
commit | 24de58f465165298aaa8f286b2592f0163706cfe (patch) | |
tree | 46cdf87f68eea42037c667cc02d54119791861fb /net/netfilter/nfnetlink_cttimeout.c | |
parent | dd705072412225a97784fe38feee2ebf8d14814d (diff) |
netfilter: xt_CT: allow to attach timeout policy + glue code
This patch allows you to attach the timeout policy via the
CT target, it adds a new revision of the target to ensure
backward compatibility. Moreover, it also contains the glue
code to stick the timeout object defined via nfnetlink_cttimeout
to the given flow.
Example usage (it requires installing the nfct tool and
libnetfilter_cttimeout):
1) create the timeout policy:
nfct timeout add tcp-policy0 inet tcp \
established 1000 close 10 time_wait 10 last_ack 10
2) attach the timeout policy to the packet:
iptables -I PREROUTING -t raw -p tcp -j CT --timeout tcp-policy0
You have to install the following user-space software:
a) libnetfilter_cttimeout:
git://git.netfilter.org/libnetfilter_cttimeout
b) nfct:
git://git.netfilter.org/nfct
You also have to get iptables with -j CT --timeout support.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nfnetlink_cttimeout.c')
-rw-r--r-- | net/netfilter/nfnetlink_cttimeout.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 29b98971516..fec29a43de4 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -29,6 +29,7 @@ #include <net/netfilter/nf_conntrack_l3proto.h> #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_tuple.h> +#include <net/netfilter/nf_conntrack_timeout.h> #include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink_cttimeout.h> @@ -331,6 +332,38 @@ cttimeout_del_timeout(struct sock *ctnl, struct sk_buff *skb, return ret; } +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +static struct ctnl_timeout *ctnl_timeout_find_get(const char *name) +{ + struct ctnl_timeout *timeout, *matching = NULL; + + rcu_read_lock(); + list_for_each_entry_rcu(timeout, &cttimeout_list, head) { + if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) + continue; + + if (!try_module_get(THIS_MODULE)) + goto err; + + if (!atomic_inc_not_zero(&timeout->refcnt)) { + module_put(THIS_MODULE); + goto err; + } + matching = timeout; + break; + } +err: + rcu_read_unlock(); + return matching; +} + +static void ctnl_timeout_put(struct ctnl_timeout *timeout) +{ + atomic_dec(&timeout->refcnt); + module_put(THIS_MODULE); +} +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ + static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = { [IPCTNL_MSG_TIMEOUT_NEW] = { .call = cttimeout_new_timeout, .attr_count = CTA_TIMEOUT_MAX, @@ -362,6 +395,10 @@ static int __init cttimeout_init(void) "nfnetlink.\n"); goto err_out; } +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, ctnl_timeout_find_get); + RCU_INIT_POINTER(nf_ct_timeout_put_hook, ctnl_timeout_put); +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ return 0; err_out: @@ -382,6 +419,10 @@ static void __exit cttimeout_exit(void) */ kfree_rcu(cur, rcu_head); } +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL); + RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL); +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ } module_init(cttimeout_init); |