From: Eric Leblond <eric@inl.fr>
To: netfilter-devel@lists.netfilter.org
Cc: vincent@inl.fr
Subject: [PATCH] Fixed timeout for connections
Date: Sun, 05 Feb 2006 00:17:34 +0100 [thread overview]
Message-ID: <43E5360E.8070900@inl.fr> (raw)
[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This set of patches is an implementation of the feature discussed in :
https://lists.netfilter.org/pipermail/netfilter-devel/2006-January/023127.html
Basically, it adds the capability a fixed conntrack timeout from
userspace to be able to define an efficient connection expiration policy.
It only applies for now on ip_conntrack. I will work on nf_conntrack
support afterward if the current code seems correct.
The option -T has been added to the conntrack tool. The command :
conntrack -U -p tcp -s 192.168.1.2 -d 81.8.121.136 \\
--orig-port-src 33880 --orig-port-dst 993 -T 300
will force the connection to be destroyed 300 seconds after the call.
fixed_timeout.patch applies to linux git tree
libnetfilter_conntrack_fixed_timeout.patch to libnetfilter_conntrack svn
conntrack_fixed_timeout.patch to conntrack svn
Best regards,
- --
Eric Leblond
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFD5TYOnxA7CdMWjzIRArFcAKCSY2jCP8upI+fon2c5u8xUEgc2jgCfYaX/
pcq6hw4hbx0bRs2TMCojpoE=
=+FUO
-----END PGP SIGNATURE-----
[-- Attachment #2: fixed_timeout.patch --]
[-- Type: text/x-patch, Size: 6527 bytes --]
Signed-off-by: Eric Leblond <eric@inl.fr>
---
include/linux/netfilter/nfnetlink_conntrack.h | 3 ++
include/linux/netfilter_ipv4/ip_conntrack.h | 6 ++++
net/ipv4/netfilter/Kconfig | 12 +++++++++
net/ipv4/netfilter/ip_conntrack_core.c | 29 ++++++++++++++++-----
net/ipv4/netfilter/ip_conntrack_netlink.c | 35 ++++++++++++++++++++++++-
5 files changed, 77 insertions(+), 8 deletions(-)
e55274cbfe9a0ae13e1c78da1308eb25cbe04517
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 668ec94..fefc11f 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -29,6 +29,9 @@ enum ctattr_type {
CTA_HELP,
CTA_NAT,
CTA_TIMEOUT,
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ CTA_FIXED_TIMEOUT,
+#endif
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 215765f..9e2ad88 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -82,7 +82,11 @@ struct ip_conntrack
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
-
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ /* Is timeout fixed ? */
+ uint32_t fixed_timeout;
+#endif
+
#ifdef CONFIG_IP_NF_CT_ACCT
/* Accounting Information (same cache line as other written members) */
struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index db78303..3ad3355 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -46,6 +46,18 @@ config IP_NF_CT_ACCT
If unsure, say `N'.
+config IP_NF_CT_FIXED_TIMEOUT
+ bool "Connection tracking fixed timeout"
+ depends on IP_NF_CONNTRACK
+ help
+ If this option is enabled, the connection tracking code will
+ be able to have connection that will expire automatically after
+ a given time.
+
+ This feature can be used with libnetfilter_conntrack library.
+
+ If unsure, say `N'.
+
config IP_NF_CONNTRACK_MARK
bool 'Connection mark tracking support'
depends on IP_NF_CONNTRACK
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 84c66db..95f086b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -488,6 +488,8 @@ __ip_conntrack_confirm(struct sk_buff **
weird delay cases. */
ct->timeout.expires += jiffies;
add_timer(&ct->timeout);
+
+
atomic_inc(&ct->ct_general.use);
set_bit(IPS_CONFIRMED_BIT, &ct->status);
CONNTRACK_STAT_INC(insert);
@@ -724,11 +726,20 @@ init_conntrack(struct ip_conntrack_tuple
/* this is ugly, but there is no other place where to put it */
conntrack->nat.masq_index = exp->master->nat.masq_index;
#endif
+
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ /* fixed_timeout of related connection is the one of master */
+ conntrack->fixed_timeout=exp->master->fixed_timeout;
+#endif
nf_conntrack_get(&conntrack->master->ct_general);
CONNTRACK_STAT_INC(expect_new);
} else {
conntrack->helper = __ip_conntrack_helper_find(&repl_tuple);
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ /* init fixed_timeout to 0 (do not finish) */
+ conntrack->fixed_timeout=0;
+#endif
CONNTRACK_STAT_INC(new);
}
@@ -1135,12 +1146,18 @@ void __ip_ct_refresh_acct(struct ip_conn
ct->timeout.expires = extra_jiffies;
event = IPCT_REFRESH;
} else {
- /* Need del_timer for race avoidance (may already be dying). */
- if (del_timer(&ct->timeout)) {
- ct->timeout.expires = jiffies + extra_jiffies;
- add_timer(&ct->timeout);
- event = IPCT_REFRESH;
- }
+ /* Need del_timer for race avoidance (may already be dying). */
+ if (del_timer(&ct->timeout)) {
+ ct->timeout.expires = jiffies + extra_jiffies;
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ if ((ct->fixed_timeout) &&
+ (ct->timeout.expires > jiffies+ ct->fixed_timeout *HZ)) {
+ ct->timeout.expires = jiffies + ct->fixed_timeout * HZ;
+ }
+#endif
+ add_timer(&ct->timeout);
+ event = IPCT_REFRESH;
+ }
}
#ifdef CONFIG_IP_NF_CT_ACCT
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index c9ebbe0..10688cc 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -42,7 +42,7 @@
MODULE_LICENSE("GPL");
-static char __initdata version[] = "0.90";
+static char __initdata version[] = "0.91";
#if 0
#define DEBUGP printk
@@ -942,6 +942,20 @@ ctnetlink_change_timeout(struct ip_connt
}
static inline int
+ctnetlink_check_timeout(struct ip_conntrack *ct)
+{
+ if (ct->timeout.expires > jiffies+ ct->fixed_timeout *HZ) {
+ if (!del_timer(&ct->timeout))
+ return -ETIME;
+ ct->timeout.expires = jiffies + ct->fixed_timeout * HZ;
+ add_timer(&ct->timeout);
+ }
+ return 0;
+}
+
+
+
+static inline int
ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
{
struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
@@ -979,6 +993,15 @@ ctnetlink_change_conntrack(struct ip_con
return err;
}
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ if (cda[CTA_FIXED_TIMEOUT-1]) {
+ ct->fixed_timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_FIXED_TIMEOUT-1]));
+ err = ctnetlink_check_timeout(ct);
+ if (err < 0)
+ return err;
+ }
+#endif
+
if (cda[CTA_STATUS-1]) {
err = ctnetlink_change_status(ct, cda);
if (err < 0)
@@ -1018,7 +1041,17 @@ ctnetlink_create_conntrack(struct nfattr
goto err;
ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+ /* we admit jiffies delay on timeout even if is fixed */
ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
+
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+ if (cda[CTA_FIXED_TIMEOUT-1]) {
+ ct->fixed_timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_FIXED_TIMEOUT-1]));
+ } else {
+ ct->fixed_timeout = 0;
+ }
+#endif
+
ct->status |= IPS_CONFIRMED;
err = ctnetlink_change_status(ct, cda);
--
1.1.5
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: libnetfilter_conntrack_fixed_timeout.patch --]
[-- Type: text/x-patch; name="libnetfilter_conntrack_fixed_timeout.patch", Size: 3867 bytes --]
Index: include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
===================================================================
--- include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h (révision 6458)
+++ include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h (copie de travail)
@@ -29,6 +29,7 @@
CTA_HELP,
CTA_NAT,
CTA_TIMEOUT,
+ CTA_FIXED_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
@@ -120,7 +121,6 @@
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
- CTA_EXPECT_QUEUENR,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
Index: include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- include/libnetfilter_conntrack/libnetfilter_conntrack.h (révision 6458)
+++ include/libnetfilter_conntrack/libnetfilter_conntrack.h (copie de travail)
@@ -89,6 +89,7 @@
struct nfct_tuple tuple[NFCT_DIR_MAX];
u_int32_t timeout;
+ u_int32_t fixed_timeout;
u_int32_t mark;
u_int32_t status;
u_int32_t use;
@@ -125,19 +126,22 @@
NFCT_TIMEOUT_BIT = 2,
NFCT_TIMEOUT = (1 << NFCT_TIMEOUT_BIT),
- NFCT_MARK_BIT = 3,
+ NFCT_FIXED_TIMEOUT_BIT = 3,
+ NFCT_FIXED_TIMEOUT = (1 << NFCT_FIXED_TIMEOUT_BIT),
+
+ NFCT_MARK_BIT = 4,
NFCT_MARK = (1 << NFCT_MARK_BIT),
- NFCT_COUNTERS_ORIG_BIT = 4,
+ NFCT_COUNTERS_ORIG_BIT = 5,
NFCT_COUNTERS_ORIG = (1 << NFCT_COUNTERS_ORIG_BIT),
- NFCT_COUNTERS_RPLY_BIT = 5,
+ NFCT_COUNTERS_RPLY_BIT = 6,
NFCT_COUNTERS_RPLY = (1 << NFCT_COUNTERS_RPLY_BIT),
- NFCT_USE_BIT = 6,
+ NFCT_USE_BIT = 7,
NFCT_USE = (1 << NFCT_USE_BIT),
- NFCT_ID_BIT = 7,
+ NFCT_ID_BIT = 8,
NFCT_ID = (1 << NFCT_ID_BIT)
};
Index: src/libnetfilter_conntrack.c
===================================================================
--- src/libnetfilter_conntrack.c (révision 6458)
+++ src/libnetfilter_conntrack.c (copie de travail)
@@ -517,6 +517,11 @@
flags |= NFCT_TIMEOUT;
}
+ if (cda[CTA_FIXED_TIMEOUT-1]) {
+ ct.fixed_timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_FIXED_TIMEOUT-1]));
+ flags |= NFCT_FIXED_TIMEOUT;
+ }
+
if (cda[CTA_MARK-1]) {
ct.mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
flags |= NFCT_MARK;
@@ -633,6 +638,9 @@
if (flags & NFCT_TIMEOUT)
size += nfct_sprintf_timeout(buf+size, ct);
+ if (flags & NFCT_FIXED_TIMEOUT)
+ size += nfct_sprintf_timeout(buf+size, ct);
+
if (flags & NFCT_PROTOINFO)
size += nfct_sprintf_protoinfo(buf+size, ct);
@@ -922,6 +930,7 @@
char buf[NFCT_BUFSIZE];
u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
u_int32_t timeout = htonl(ct->timeout);
+ u_int32_t fixed_timeout = htonl(ct->fixed_timeout);
u_int32_t mark = htonl(ct->mark);
u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
@@ -943,6 +952,10 @@
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
sizeof(u_int32_t));
+
+ if (fixed_timeout)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_FIXED_TIMEOUT, &fixed_timeout,
+ sizeof(u_int32_t));
if (ct->mark != 0)
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
@@ -962,6 +975,7 @@
int err;
u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
u_int32_t timeout = htonl(ct->timeout);
+ u_int32_t fixed_timeout = htonl(ct->fixed_timeout);
u_int32_t id = htonl(ct->id);
u_int32_t mark = htonl(ct->mark);
u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
@@ -984,7 +998,12 @@
if (ct->timeout != 0)
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
sizeof(u_int32_t));
+
+ if (ct->fixed_timeout != 0)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_FIXED_TIMEOUT, &fixed_timeout,
+ sizeof(u_int32_t));
+
if (ct->mark != 0)
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
sizeof(u_int32_t));
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: conntrack_fixed_timeout.patch --]
[-- Type: text/x-patch; name="conntrack_fixed_timeout.patch", Size: 3326 bytes --]
Index: include/conntrack.h
===================================================================
--- include/conntrack.h (révision 6458)
+++ include/conntrack.h (copie de travail)
@@ -85,37 +85,40 @@
CT_OPT_TIMEOUT_BIT = 5,
CT_OPT_TIMEOUT = (1 << CT_OPT_TIMEOUT_BIT),
- CT_OPT_STATUS_BIT = 6,
+ CT_OPT_FIXED_TIMEOUT_BIT = 6,
+ CT_OPT_FIXED_TIMEOUT = (1 << CT_OPT_FIXED_TIMEOUT_BIT),
+
+ CT_OPT_STATUS_BIT = 7,
CT_OPT_STATUS = (1 << CT_OPT_STATUS_BIT),
- CT_OPT_ZERO_BIT = 7,
+ CT_OPT_ZERO_BIT = 8,
CT_OPT_ZERO = (1 << CT_OPT_ZERO_BIT),
- CT_OPT_EVENT_MASK_BIT = 8,
+ CT_OPT_EVENT_MASK_BIT = 9,
CT_OPT_EVENT_MASK = (1 << CT_OPT_EVENT_MASK_BIT),
- CT_OPT_EXP_SRC_BIT = 9,
+ CT_OPT_EXP_SRC_BIT = 10,
CT_OPT_EXP_SRC = (1 << CT_OPT_EXP_SRC_BIT),
- CT_OPT_EXP_DST_BIT = 10,
+ CT_OPT_EXP_DST_BIT = 11,
CT_OPT_EXP_DST = (1 << CT_OPT_EXP_DST_BIT),
- CT_OPT_MASK_SRC_BIT = 11,
+ CT_OPT_MASK_SRC_BIT = 12,
CT_OPT_MASK_SRC = (1 << CT_OPT_MASK_SRC_BIT),
- CT_OPT_MASK_DST_BIT = 12,
+ CT_OPT_MASK_DST_BIT = 13,
CT_OPT_MASK_DST = (1 << CT_OPT_MASK_DST_BIT),
- CT_OPT_NATRANGE_BIT = 13,
+ CT_OPT_NATRANGE_BIT = 14,
CT_OPT_NATRANGE = (1 << CT_OPT_NATRANGE_BIT),
- CT_OPT_MARK_BIT = 14,
+ CT_OPT_MARK_BIT = 15,
CT_OPT_MARK = (1 << CT_OPT_MARK_BIT),
- CT_OPT_ID_BIT = 15,
+ CT_OPT_ID_BIT = 16,
CT_OPT_ID = (1 << CT_OPT_ID_BIT),
- CT_OPT_FAMILY_BIT = 16,
+ CT_OPT_FAMILY_BIT = 17,
CT_OPT_FAMILY = (1 << CT_OPT_FAMILY_BIT),
CT_OPT_MAX_BIT = CT_OPT_FAMILY_BIT
Index: src/conntrack.c
===================================================================
--- src/conntrack.c (révision 6458)
+++ src/conntrack.c (copie de travail)
@@ -80,6 +80,7 @@
{"reply-dst", 1, 0, 'q'},
{"protonum", 1, 0, 'p'},
{"timeout", 1, 0, 't'},
+ {"Timeout", 1, 0, 'T'},
{"status", 1, 0, 'u'},
{"zero", 0, 0, 'z'},
{"event-mask", 1, 0, 'e'},
@@ -569,6 +570,7 @@
" -p, --protonum proto\t\tLayer 4 Protocol, eg. 'tcp'\n"
" -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
" -t, --timeout timeout\t\tSet timeout\n"
+ " -T, --Timeout fixed timeout\t\tSet fixed timeout\n"
" -u, --status status\t\tSet status, eg. ASSURED\n"
" -i, --id [id]\t\t\tShow or set conntrack ID\n"
;
@@ -595,6 +597,7 @@
static struct nfct_conntrack *ct;
static struct nfct_expect *exp;
static unsigned long timeout;
+static unsigned long fixed_timeout;
static unsigned int status;
static unsigned int mark;
static unsigned int id = NFCT_ANY_ID;
@@ -611,7 +614,7 @@
struct nfct_conntrack_compare *pcmp;
while ((c = getopt_long(argc, argv,
- "L::I::U::D::G::E::F::hVs:d:r:q:p:t:u:e:a:z[:]:{:}:m:i::f:",
+ "L::I::U::D::G::E::F::hVs:d:r:q:p:t:T:u:e:a:z[:]:{:}:m:i::f:",
opts, NULL)) != -1) {
switch(c) {
case 'L':
@@ -735,6 +738,12 @@
if (optarg)
timeout = atol(optarg);
break;
+ case 'T':
+ options |= CT_OPT_FIXED_TIMEOUT;
+ if (optarg)
+ fixed_timeout = atol(optarg);
+ break;
+
case 'u': {
if (!optarg)
continue;
@@ -974,6 +983,9 @@
ct = nfct_conntrack_alloc(&orig, &reply, timeout,
&proto, status, mark, id,
NULL);
+ if (options & CT_OPT_FIXED_TIMEOUT) {
+ ct->fixed_timeout = fixed_timeout;
+ }
if (!ct)
exit_error(OTHER_PROBLEM, "Not enough memory");
next reply other threads:[~2006-02-04 23:17 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-04 23:17 Eric Leblond [this message]
2006-02-05 23:08 ` [PATCH] Fixed timeout for connections Eric Leblond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43E5360E.8070900@inl.fr \
--to=eric@inl.fr \
--cc=netfilter-devel@lists.netfilter.org \
--cc=vincent@inl.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.