All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fixed timeout for connections
@ 2006-02-04 23:17 Eric Leblond
  2006-02-05 23:08 ` Eric Leblond
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Leblond @ 2006-02-04 23:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: vincent

[-- 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");
 		

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fixed timeout for connections
  2006-02-04 23:17 [PATCH] Fixed timeout for connections Eric Leblond
@ 2006-02-05 23:08 ` Eric Leblond
  0 siblings, 0 replies; 2+ messages in thread
From: Eric Leblond @ 2006-02-05 23:08 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, vincent

[-- Attachment #1: Type: text/plain, Size: 737 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Please ignore previous kernel patch (fixed_timeout.patch) and replace it
with the one attached to this mail.

Eric Leblond wrote:
> 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.




-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFD5oWAnxA7CdMWjzIRAggXAJ9AVc34NngmU3fIw+1mpwXFzLGLIACfefhG
Tq5O8K6n/+VhMB7WtXcPeEI=
=z9gh
-----END PGP SIGNATURE-----

[-- Attachment #2: fixed_timeout.patch --]
[-- Type: text/x-patch, Size: 6743 bytes --]

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..f5e9070 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 ? */
+        struct timer_list 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..b1062ca 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -319,6 +319,11 @@ destroy_conntrack(struct nf_conntrack *n
 	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
 	IP_NF_ASSERT(!timer_pending(&ct->timeout));
 
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+        if (timer_pending(&ct->fixed_timeout)) {
+                del_timer(&ct->fixed_timeout);
+        }
+#endif
 	ip_conntrack_event(IPCT_DESTROY, ct);
 	set_bit(IPS_DYING_BIT, &ct->status);
 
@@ -359,6 +364,15 @@ static void death_by_timeout(unsigned lo
 {
 	struct ip_conntrack *ct = (void *)ul_conntrack;
 
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+        /* delete the timer which has not timeout */
+        if (timer_pending(&ct->timeout)) {
+                del_timer(&ct->timeout);
+        }
+        if (timer_pending(&ct->fixed_timeout)) {
+                del_timer(&ct->fixed_timeout);
+        }
+#endif
 	write_lock_bh(&ip_conntrack_lock);
 	/* Inside lock so preempt is disabled on module removal path.
 	 * Otherwise we can get spurious warnings. */
@@ -670,6 +684,12 @@ struct ip_conntrack *ip_conntrack_alloc(
 	conntrack->timeout.data = (unsigned long)conntrack;
 	conntrack->timeout.function = death_by_timeout;
 
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+	init_timer(&conntrack->fixed_timeout);
+	conntrack->fixed_timeout.data = (unsigned long)conntrack;
+	conntrack->fixed_timeout.function = death_by_timeout;
+#endif
+
 	atomic_inc(&ip_conntrack_count);
 
 	return conntrack;
@@ -724,6 +744,7 @@ 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
+
 		nf_conntrack_get(&conntrack->master->ct_general);
 		CONNTRACK_STAT_INC(expect_new);
 	} else {
@@ -1135,12 +1156,12 @@ 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;
+                       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..568006f 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,25 @@ ctnetlink_change_timeout(struct ip_connt
 }
 
 static inline int
+ctnetlink_change_fixed_timeout(struct ip_conntrack *ct, struct nfattr *cda[])
+{
+	u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_FIXED_TIMEOUT-1]));
+	
+        /* test if timer has already been set */
+        if (timer_pending(&ct->fixed_timeout)){
+	        if (!del_timer(&ct->fixed_timeout))
+		        return -ETIME;
+        }
+
+	ct->fixed_timeout.expires = jiffies + timeout * HZ;
+	add_timer(&ct->fixed_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 +998,14 @@ ctnetlink_change_conntrack(struct ip_con
 			return err;
 	}
 
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+	if (cda[CTA_FIXED_TIMEOUT-1]) {
+		err = ctnetlink_change_fixed_timeout(ct, cda);
+		if (err < 0)
+			return err;
+        }
+#endif
+
 	if (cda[CTA_STATUS-1]) {
 		err = ctnetlink_change_status(ct, cda);
 		if (err < 0)
@@ -1018,7 +1045,15 @@ 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.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_FIXED_TIMEOUT-1]));
+        }
+#endif
+        
 	ct->status |= IPS_CONFIRMED;
 
 	err = ctnetlink_change_status(ct, cda);
@@ -1039,6 +1074,13 @@ ctnetlink_create_conntrack(struct nfattr
 	ct->helper = ip_conntrack_helper_find_get(rtuple);
 
 	add_timer(&ct->timeout);
+
+#ifdef CONFIG_IP_NF_CT_FIXED_TIMEOUT
+	if (cda[CTA_FIXED_TIMEOUT-1]) {
+	        add_timer(&ct->fixed_timeout);
+        }
+#endif
+
 	ip_conntrack_hash_insert(ct);
 
 	if (ct->helper)

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-02-05 23:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-04 23:17 [PATCH] Fixed timeout for connections Eric Leblond
2006-02-05 23:08 ` Eric Leblond

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.