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