Hi,

This patch provides a new target called LOWTW, which gives the ability to
change the timeout in the TIME-WAIT state on connections in the conntrack
table. It always accept packets.

This is useful when you have a _lot_ of short-lived connections through
your firewall (eg. web traffic), because each conntrack have a timeout of
2 minutes (default, hard-coded) the conntrack table could be filled with
entries in the TIME-WAIT state.

The patch is simple, it just sets the timeout (specified with the
"--lowtw-set n", where n is the timeout in seconds) on the conntrack when
the conntrack enters the TIME-WAIT state.

E.g. to avoid the conntrack table to filled with entries from web traffic
from your LAN do: iptables -A FORWARD -p tcp -source 192.168.0.0/24
--dport 80 -j LOWTW --lowtw-set 10

The patch was tested against 2.4.18.

Any comments, bug-reports or questions are welcome.

Regards
Mikkel, Torben and Carsten
{mrb|mariachi|stiborg}@cs.auc.dk
diff -Nru iptables-1.2.6a/extensions/Makefile iptables-lowtw/extensions/Makefile
--- iptables-1.2.6a/extensions/Makefile Thu Mar 14 13:13:48 2002
+++ iptables-lowtw/extensions/Makefile  Fri Mar 22 12:00:46 2002
@@ -1,6 +1,6 @@
 #! /usr/bin/make
 
-PF_EXT_SLIB:=ah dscp esp icmp length limit mac mark multiport owner standard state 
tcp tcpmss tos ttl udp unclean DNAT DSCP ECN LOG MARK MASQUERADE MIRROR REDIRECT 
REJECT SAME SNAT TCPMSS TOS ULOG
+PF_EXT_SLIB:=ah dscp esp icmp length limit mac mark multiport owner standard state 
+tcp tcpmss tos ttl udp unclean DNAT DSCP ECN LOG MARK MASQUERADE MIRROR REDIRECT 
+REJECT SAME SNAT TCPMSS TOS ULOG LOWTW
 PF6_EXT_SLIB:=icmpv6 length limit mac mark multiport owner standard tcp udp LOG MARK
 
 # The following may not be present, but compile them anyway.
diff -Nru iptables-1.2.6a/extensions/libipt_LOWTW.c 
iptables-lowtw/extensions/libipt_LOWTW.c
--- iptables-1.2.6a/extensions/libipt_LOWTW.c   Thu Jan  1 01:00:00 1970
+++ iptables-lowtw/extensions/libipt_LOWTW.c    Mon Apr  8 16:08:33 2002
@@ -0,0 +1,106 @@
+/* Shared library add-on to iptables for the LOWTW target */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <iptables.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_LOWTW.h>
+
+/* used for bitmask */
+#define IPT_LOWTW_USED 1
+
+static void init(struct ipt_entry_target *t, unsigned int *nfcache) 
+{
+}
+
+static void help(void) 
+{
+       printf(
+"LOWTW target v%s option\n"
+"  --lowtw-set value           Set TIME-WAIT timeout value to <value>\n"
+, NETFILTER_VERSION);
+}
+
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+               const struct ipt_entry *entry,
+               struct ipt_entry_target **target)
+{
+       struct ipt_LOWTW_info *info = (struct ipt_LOWTW_info *) (*target)->data;
+       unsigned int twtimeout;
+
+       if (*flags & IPT_LOWTW_USED) {
+               exit_error(PARAMETER_PROBLEM, 
+                               "Can't specify LOWTW option twice");
+       }
+
+       if (!optarg) 
+               exit_error(PARAMETER_PROBLEM, 
+                               "LOWTW: You must specify a value");
+
+       if (check_inverse(optarg, &invert, NULL, 0))
+               exit_error(PARAMETER_PROBLEM,
+                               "LOWTW: unexpected `!'");
+
+       if (string_to_number(optarg, 0, 255, &twtimeout) == -1) {
+         exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", optarg);
+       }
+
+       info->twtimeout = atoi(optarg);
+       *flags |= IPT_LOWTW_USED;
+
+       return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+       if (!(flags & IPT_LOWTW_USED))
+               exit_error(PARAMETER_PROBLEM,
+                               "LOWTW: You must specify an action");
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+       const struct ipt_LOWTW_info *info =
+               (const struct ipt_LOWTW_info *)target->data;
+
+       printf("--lowtw-set %u ", info->twtimeout);
+}
+
+
+/* Prints out the targinfo. */
+static void print(const struct ipt_ip *ip,
+               const struct ipt_entry_target *target, int numeric)
+{
+       const struct ipt_LOWTW_info *info =
+               (struct ipt_LOWTW_info *) target->data;
+       printf("timeout %u secs ", info->twtimeout);
+}
+
+static struct option opts[] = {
+       { "lowtw-set", 1, 0, '1' },
+       { 0 }
+};
+
+static
+struct iptables_target LOWTW = { NULL, 
+       "LOWTW",
+       NETFILTER_VERSION,
+       IPT_ALIGN(sizeof(struct ipt_LOWTW_info)),
+       IPT_ALIGN(sizeof(struct ipt_LOWTW_info)),
+       &help,
+       &init,
+       &parse,
+       &final_check,
+       &print,
+       &save,
+       opts 
+};
+
+void _init(void)
+{
+       register_target(&LOWTW);
+}
diff -Nru linux-2.4.18/include/linux/netfilter_ipv4/ipt_LOWTW.h 
linux-lowtw/include/linux/netfilter_ipv4/ipt_LOWTW.h
--- linux-2.4.18/include/linux/netfilter_ipv4/ipt_LOWTW.h       Thu Jan  1 01:00:00 
1970
+++ linux-lowtw/include/linux/netfilter_ipv4/ipt_LOWTW.h        Fri Mar 22 11:58:53 
+2002
@@ -0,0 +1,5 @@
+/* hold the timeout, this structure is used both by 
+ * kernel and user space to communicate */
+struct ipt_LOWTW_info {
+  u_int8_t twtimeout;
+};
diff -Nru linux-2.4.18/net/ipv4/netfilter/Config.in 
linux-lowtw/net/ipv4/netfilter/Config.in
--- linux-2.4.18/net/ipv4/netfilter/Config.in   Mon Feb 25 20:38:14 2002
+++ linux-lowtw/net/ipv4/netfilter/Config.in    Mon Apr  8 16:21:16 2002
@@ -73,6 +73,7 @@
   if [ "$CONFIG_IP_NF_MANGLE" != "n" ]; then
     dep_tristate '    TOS target support' CONFIG_IP_NF_TARGET_TOS 
$CONFIG_IP_NF_MANGLE
     dep_tristate '    MARK target support' CONFIG_IP_NF_TARGET_MARK 
$CONFIG_IP_NF_MANGLE
+    dep_tristate '    LOWTW target support' CONFIG_IP_NF_TARGET_LOWTW 
+$CONFIG_IP_NF_IPTABLES
   fi
   dep_tristate '  LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
   if [ "$CONFIG_NETLINK" != "n" ]; then
diff -Nru linux-2.4.18/net/ipv4/netfilter/Makefile 
linux-lowtw/net/ipv4/netfilter/Makefile
--- linux-2.4.18/net/ipv4/netfilter/Makefile    Mon Feb 25 20:38:14 2002
+++ linux-lowtw/net/ipv4/netfilter/Makefile     Mon Apr  8 16:26:08 2002
@@ -76,6 +76,7 @@
 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
+obj-$(CONFIG_IP_NF_TARGET_LOWTW) += ipt_LOWTW.o
 
 # backwards compatibility 
 obj-$(CONFIG_IP_NF_COMPAT_IPCHAINS) += ipchains.o
diff -Nru linux-2.4.18/net/ipv4/netfilter/ipt_LOWTW.c 
linux-lowtw/net/ipv4/netfilter/ipt_LOWTW.c
--- linux-2.4.18/net/ipv4/netfilter/ipt_LOWTW.c Thu Jan  1 01:00:00 1970
+++ linux-lowtw/net/ipv4/netfilter/ipt_LOWTW.c  Mon Apr  8 14:46:31 2002
@@ -0,0 +1,71 @@
+/* LOWTW. Low TIME-WAIT timeout on conntracks. */
+#include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/inetdevice.h>
+#include <net/protocol.h>
+#include <net/checksum.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ipt_LOWTW.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int
+lowtw_check(const char *tablename,
+              const struct ipt_entry *e,
+              void *targinfo,
+              unsigned int targinfosize,
+              unsigned int hook_mask)
+{
+       return 1;
+}
+
+static unsigned int
+lowtw_target(struct sk_buff **pskb,
+               unsigned int hooknum,
+               const struct net_device *in,
+               const struct net_device *out,
+               const void *targinfo,
+               void *userinfo)
+{ 
+        /* this holds the timeout specified on the cmd-line */
+       const struct ipt_LOWTW_info *info = targinfo;
+       struct ip_conntrack *ct;
+       enum ip_conntrack_info ctinfo;
+       /* find the relavant conntrack */
+       ct = ip_conntrack_get(*pskb, &ctinfo);
+       /* if it is in the TW state */
+       if (ct->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) { 
+         /* then set the timeout */
+         ip_ct_refresh(ct, info->twtimeout * HZ);
+         /* printk("TW timeout %i secs\n", info->twtimeout); */
+       } 
+       return IPT_CONTINUE;
+}
+
+static struct ipt_target lowtw_reg
+= { { NULL, NULL }, "LOWTW", lowtw_target, lowtw_check, NULL,
+    THIS_MODULE };
+
+static int __init init(void)
+{
+       return ipt_register_target(&lowtw_reg);
+}
+
+static void __exit fini(void)
+{
+       ipt_unregister_target(&lowtw_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");

Reply via email to