diff -urN iptables-1.4.0-orig/extensions/Makefile iptables-1.4.0/extensions/Makefile
--- iptables-1.4.0-orig/extensions/Makefile	2009-02-18 19:15:03.000000000 +0800
+++ iptables-1.4.0/extensions/Makefile	2009-02-18 19:15:03.000000000 +0800
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=ratelimit connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
diff -urN iptables-1.4.0-orig/extensions/libxt_ratelimit.c iptables-1.4.0/extensions/libxt_ratelimit.c
--- iptables-1.4.0-orig/extensions/libxt_ratelimit.c	1970-01-01 08:00:00.000000000 +0800
+++ iptables-1.4.0/extensions/libxt_ratelimit.c	2009-02-18 19:15:03.000000000 +0800
@@ -0,0 +1,233 @@
+/* Shared library add-on to iptables to add connection limit support. */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <getopt.h>
+#include <iptables.h>
+#include "../include/linux/netfilter/xt_ratelimit.h"
+
+static void ratelimit_help(void)
+{
+	printf(
+"ratelimit v%s options:\n"
+" --ip-range ip-ip       Match source IP in the specified range\n"
+" --tx-ratelimit n        match if the tx rate above n Kbps\n"
+" --rx-ratelimit n        match if the rx rate above n Kbps\n"
+"\n", IPTABLES_VERSION);
+}
+
+static const struct option ratelimit_opts[] = {
+	{"tx-ratelimit", 1, NULL, '1'},
+	{"rx-ratelimit", 1, NULL, '2'},
+	{"ip-range", 1, NULL, '3'},
+	{NULL},
+};
+
+static void ratelimit_init(struct xt_entry_match *match)
+{
+	struct xt_ratelimit_info *info = (void *)match->data;
+	info->tx_limit = 0;
+	info->rx_limit = 0;
+	info->src.max_ip = 0;
+	info->src.min_ip = 0;
+}
+
+static void
+parse_iprange(char *arg, struct ipt_iprange *range)
+{
+	char *dash;
+	struct in_addr *ip;
+
+	dash = strchr(arg, '-');
+	if (dash)
+		*dash = '\0';
+		
+	ip = dotted_to_addr(arg);
+	if (!ip)
+		exit_error(PARAMETER_PROBLEM, "iprange match: Bad IP address `%s'\n", 
+			   arg);
+	range->min_ip = ip->s_addr;
+
+	if (dash) {
+		ip = dotted_to_addr(dash+1);
+		if (!ip)
+			exit_error(PARAMETER_PROBLEM, "iprange match: Bad IP address `%s'\n",
+				   dash+1);
+		range->max_ip = ip->s_addr;
+	} else
+		range->max_ip = range->min_ip;
+}
+
+static int ratelimit_parse(int c, char **argv, int invert, unsigned int *flags,
+                           struct xt_ratelimit_info *info, unsigned int family)
+{
+	char *err;
+
+	switch (c) {
+	case '1':
+		if (*flags & 0x1)
+			exit_error(PARAMETER_PROBLEM,
+				"--tx-ratelimit may be given only once");
+		*flags |= 0x1;
+		info->tx_limit   = strtoul(argv[optind-1], NULL, 0);
+		if(info->tx_limit < 1 || info->tx_limit > 65000)
+			exit_error(PARAMETER_PROBLEM,
+				"--tx-ratelimit number must be between 1-65000");
+		break;
+
+	case '2':
+		if (*flags & 0x2)
+			exit_error(PARAMETER_PROBLEM,
+				"--rx-ratelimit may be given only once");
+		*flags |= 0x2;
+		info->rx_limit   = strtoul(argv[optind-1], NULL, 0);
+		if(info->rx_limit < 1 || info->rx_limit > 65000)
+			exit_error(PARAMETER_PROBLEM,
+				"--rx-ratelimit number must be between 1-65000");
+		break;
+
+	case '3':
+		if (*flags & 0x4)
+			exit_error(PARAMETER_PROBLEM,
+				"--ip-range may be given only once");
+		*flags |= 0x4;
+		parse_iprange(optarg, &info->src);
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static int ratelimit_parse4(int c, char **argv, int invert,
+                            unsigned int *flags, const void *entry,
+                            struct xt_entry_match **match)
+{
+	return ratelimit_parse(c, argv, invert, flags,
+	       (void *)(*match)->data, AF_INET);
+}
+
+static int ratelimit_parse6(int c, char **argv, int invert,
+                            unsigned int *flags, const void *entry,
+                            struct xt_entry_match **match)
+{
+	return ratelimit_parse(c, argv, invert, flags,
+	       (void *)(*match)->data, AF_INET6);
+}
+
+static void ratelimit_check(unsigned int flags)
+{
+	if (!(flags & 0x1))
+		exit_error(PARAMETER_PROBLEM,
+			"You must specify \"--tx-ratelimit\"");
+	if (!(flags & 0x2))
+		exit_error(PARAMETER_PROBLEM,
+			"You must specify \"--rx-ratelimit\"");
+	if (!(flags & 0x4))
+		exit_error(PARAMETER_PROBLEM,
+			"You must specify \"--ip-range\"");
+}
+
+static unsigned int count_bits4(u_int32_t mask)
+{
+	unsigned int bits = 0;
+
+	for (mask = ~ntohl(mask); mask != 0; mask >>= 1)
+		++bits;
+
+	return 32 - bits;
+}
+
+static unsigned int count_bits6(const u_int32_t *mask)
+{
+	unsigned int bits = 0, i;
+	u_int32_t tmp[4];
+
+	for (i = 0; i < 4; ++i)
+		for (tmp[i] = ~ntohl(mask[i]); tmp[i] != 0; tmp[i] >>= 1)
+			++bits;
+	return 128 - bits;
+}
+
+static void ratelimit_print4(const void *ip,
+                             const struct xt_entry_match *match, int numeric)
+{
+	const struct xt_ratelimit_info *info = (const void *)match->data;
+	const unsigned char *byte_min, *byte_max;
+
+	byte_min = (const unsigned char *) &(info->src.min_ip);
+	byte_max = (const unsigned char *) &(info->src.max_ip);
+	printf("%d.%d.%d.%d-%d.%d.%d.%d ", 
+		byte_min[0], byte_min[1], byte_min[2], byte_min[3],
+		byte_max[0], byte_max[1], byte_max[2], byte_max[3]);
+	printf("#txrate<%uKbps/rxrate<%uKbps ", info->tx_limit, info->rx_limit);
+}
+
+static void ratelimit_print6(const void *ip,
+                             const struct xt_entry_match *match, int numeric)
+{
+	const struct xt_ratelimit_info *info = (const void *)match->data;
+
+	printf("#txrate<%u/rxrate<%u ", info->tx_limit, info->rx_limit);
+}
+
+static void ratelimit_save4(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_ratelimit_info *info = (const void *)match->data;
+	const unsigned char *byte_min, *byte_max;
+
+	byte_min = (const unsigned char *) &(info->src.min_ip);
+	byte_max = (const unsigned char *) &(info->src.max_ip);
+	printf("--ip-range %d.%d.%d.%d-%d.%d.%d.%d --tx-ratelimit %u --rx-ratelimit %u ",
+		byte_min[0], byte_min[1], byte_min[2], byte_min[3],
+		byte_max[0], byte_max[1], byte_max[2], byte_max[3],
+		info->tx_limit, info->rx_limit);
+}
+
+static void ratelimit_save6(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_ratelimit_info *info = (const void *)match->data;
+
+	printf("--tx-ratelimit %u --rx-ratelimit %u ",
+			info->tx_limit, info->rx_limit);
+}
+
+static struct xtables_match ratelimit_match = {
+	.name          = "ratelimit",
+	.family        = AF_INET,
+	.version       = IPTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof(struct xt_ratelimit_info)),
+	.userspacesize = offsetof(struct xt_ratelimit_info, data),
+	.help          = ratelimit_help,
+	.init          = ratelimit_init,
+	.parse         = ratelimit_parse4,
+	.final_check   = ratelimit_check,
+	.print         = ratelimit_print4,
+	.save          = ratelimit_save4,
+	.extra_opts    = ratelimit_opts,
+};
+
+static struct xtables_match ratelimit_match6 = {
+	.name          = "ratelimit",
+	.family        = AF_INET6,
+	.version       = IPTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof(struct xt_ratelimit_info)),
+	.userspacesize = offsetof(struct xt_ratelimit_info, data),
+	.help          = ratelimit_help,
+	.init          = ratelimit_init,
+	.parse         = ratelimit_parse6,
+	.final_check   = ratelimit_check,
+	.print         = ratelimit_print6,
+	.save          = ratelimit_save6,
+	.extra_opts    = ratelimit_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&ratelimit_match);
+	xtables_register_match(&ratelimit_match6);
+}
diff -urN iptables-1.4.0-orig/include/linux/netfilter/xt_ratelimit.h iptables-1.4.0/include/linux/netfilter/xt_ratelimit.h
--- iptables-1.4.0-orig/include/linux/netfilter/xt_ratelimit.h	1970-01-01 08:00:00.000000000 +0800
+++ iptables-1.4.0/include/linux/netfilter/xt_ratelimit.h	2009-02-23 12:26:25.000000000 +0800
@@ -0,0 +1,39 @@
+#ifndef _XT_RATELIMIT_H
+#define _XT_RATELIMIT_H
+
+struct xt_ratelimit_data;
+
+#define	MAX_BLIMIT_CNT			10
+
+enum {
+	RATE_LIMIT_DIRECTION_DOWNLINK = 0,
+	RATE_LIMIT_DIRECTION_UPLINK,
+	RATE_LIMIT_DIRECTION_MAX
+};
+
+struct ipt_iprange {
+	/* Inclusive: network order. */
+	__be32 min_ip, max_ip;
+};
+
+/* bandwidth limit ip-range */
+struct bl_iprange {
+	/* Inclusive: network order. */
+	__be32 min_ip, max_ip;
+	int used;
+};
+
+extern struct bl_iprange bandwidth_limit_ip[];
+extern int bandwidth_limit_enabled;
+extern int check_blimit_range(unsigned long addr1, unsigned long addr2);
+
+struct xt_ratelimit_info {
+	unsigned int tx_limit, rx_limit;
+	struct ipt_iprange src;
+	
+	/* this needs to be at the end */
+	struct xt_ratelimit_data *data __attribute__((aligned(8)));
+};
+
+#endif /* _XT_RATELIMIT_H */
+
