Skip to content

Commit

Permalink
netfilter: nf_ct_ext: add timeout extension
Browse files Browse the repository at this point in the history
This patch adds the timeout extension, which allows you to attach
specific timeout policies to flows.

This extension is only used by the template conntrack.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Pablo Neira Ayuso committed Mar 7, 2012
1 parent 5097846 commit dd70507
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 10 deletions.
4 changes: 4 additions & 0 deletions include/net/netfilter/nf_conntrack_extend.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ enum nf_ct_ext_id {
#endif
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
NF_CT_EXT_TSTAMP,
#endif
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
NF_CT_EXT_TIMEOUT,
#endif
NF_CT_EXT_NUM,
};
Expand All @@ -29,6 +32,7 @@ enum nf_ct_ext_id {
#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache
#define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone
#define NF_CT_EXT_TSTAMP_TYPE struct nf_conn_tstamp
#define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout

/* Extensions: optional stuff which isn't permanently in struct. */
struct nf_ct_ext {
Expand Down
78 changes: 78 additions & 0 deletions include/net/netfilter/nf_conntrack_timeout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef _NF_CONNTRACK_TIMEOUT_H
#define _NF_CONNTRACK_TIMEOUT_H

#include <net/net_namespace.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_extend.h>

#define CTNL_TIMEOUT_NAME_MAX 32

struct ctnl_timeout {
struct list_head head;
struct rcu_head rcu_head;
atomic_t refcnt;
char name[CTNL_TIMEOUT_NAME_MAX];
__u16 l3num;
__u8 l4num;
char data[0];
};

struct nf_conn_timeout {
struct ctnl_timeout *timeout;
};

#define NF_CT_TIMEOUT_EXT_DATA(__t) (unsigned int *) &((__t)->timeout->data)

static inline
struct nf_conn_timeout *nf_ct_timeout_find(const struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
return nf_ct_ext_find(ct, NF_CT_EXT_TIMEOUT);
#else
return NULL;
#endif
}

static inline
struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct,
struct ctnl_timeout *timeout,
gfp_t gfp)
{
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
struct nf_conn_timeout *timeout_ext;

timeout_ext = nf_ct_ext_add(ct, NF_CT_EXT_TIMEOUT, gfp);
if (timeout_ext == NULL)
return NULL;

timeout_ext->timeout = timeout;

return timeout_ext;
#else
return NULL;
#endif
};

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
extern int nf_conntrack_timeout_init(struct net *net);
extern void nf_conntrack_timeout_fini(struct net *net);
#else
static inline int nf_conntrack_timeout_init(struct net *net)
{
return 0;
}

static inline void nf_conntrack_timeout_fini(struct net *net)
{
return;
}
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
extern struct ctnl_timeout *(*nf_ct_timeout_find_get_hook)(const char *name);
extern void (*nf_ct_timeout_put_hook)(struct ctnl_timeout *timeout);
#endif

#endif /* _NF_CONNTRACK_TIMEOUT_H */
10 changes: 10 additions & 0 deletions net/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ config NF_CONNTRACK_EVENTS

If unsure, say `N'.

config NF_CONNTRACK_TIMEOUT
bool 'Connection tracking timeout'
depends on NETFILTER_ADVANCED
help
This option enables support for connection tracking timeout
extension. This allows you to attach timeout policies to flow
via the CT target.

If unsure, say `N'.

config NF_CONNTRACK_TIMESTAMP
bool 'Connection tracking timestamping'
depends on NETFILTER_ADVANCED
Expand Down
1 change: 1 addition & 0 deletions net/netfilter/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o

nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o

Expand Down
7 changes: 7 additions & 0 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_conntrack_timestamp.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_core.h>

Expand Down Expand Up @@ -1333,6 +1334,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
}

nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
nf_conntrack_timeout_fini(net);
nf_conntrack_ecache_fini(net);
nf_conntrack_tstamp_fini(net);
nf_conntrack_acct_fini(net);
Expand Down Expand Up @@ -1564,9 +1566,14 @@ static int nf_conntrack_init_net(struct net *net)
ret = nf_conntrack_ecache_init(net);
if (ret < 0)
goto err_ecache;
ret = nf_conntrack_timeout_init(net);
if (ret < 0)
goto err_timeout;

return 0;

err_timeout:
nf_conntrack_timeout_fini(net);
err_ecache:
nf_conntrack_tstamp_fini(net);
err_tstamp:
Expand Down
60 changes: 60 additions & 0 deletions net/netfilter/nf_conntrack_timeout.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
* (C) 2012 by Vyatta Inc. <http://www.vyatta.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 (or any later at your option).
*/

#include <linux/types.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/vmalloc.h>
#include <linux/stddef.h>
#include <linux/err.h>
#include <linux/percpu.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <linux/export.h>

#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_timeout.h>

struct ctnl_timeout *
(*nf_ct_timeout_find_get_hook)(const char *name) __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_timeout_find_get_hook);

void (*nf_ct_timeout_put_hook)(struct ctnl_timeout *timeout) __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_timeout_put_hook);

static struct nf_ct_ext_type timeout_extend __read_mostly = {
.len = sizeof(struct nf_conn_timeout),
.align = __alignof__(struct nf_conn_timeout),
.id = NF_CT_EXT_TIMEOUT,
};

int nf_conntrack_timeout_init(struct net *net)
{
int ret = 0;

if (net_eq(net, &init_net)) {
ret = nf_ct_extend_register(&timeout_extend);
if (ret < 0) {
printk(KERN_ERR "nf_ct_timeout: Unable to register "
"timeout extension.\n");
return ret;
}
}

return 0;
}

void nf_conntrack_timeout_fini(struct net *net)
{
if (net_eq(net, &init_net))
nf_ct_extend_unregister(&timeout_extend);
}
10 changes: 0 additions & 10 deletions net/netfilter/nfnetlink_cttimeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,6 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning");

struct ctnl_timeout {
struct list_head head;
struct rcu_head rcu_head;
atomic_t refcnt;
char name[CTNL_TIMEOUT_NAME_MAX];
__u16 l3num;
__u8 l4num;
char data[0];
};

static LIST_HEAD(cttimeout_list);

static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
Expand Down

0 comments on commit dd70507

Please sign in to comment.