Hi, I ran into the same problem and made a backport of ipt_recent.c for Sarge's 2.6.8. It was actually pretty simple to backport. Attached is the diff against the ipt_recent.c source file from Philipp's comment of 6 Jul 2006.
The backported module is already running in one of my systems. Works as expected so far. I'll be grateful for any feedback. Martin
--- ipt_recent.c 2007-02-20 21:57:51.000000000 +0100 +++ kernel-source-2.6.8/net/ipv4/netfilter/ipt_recent.c 2007-02-22 22:02:11.118926120 +0100 @@ -68,8 +68,8 @@ struct recent_table { }; static LIST_HEAD(tables); -static DEFINE_SPINLOCK(recent_lock); -static DEFINE_MUTEX(recent_mutex); +static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED; +static DECLARE_MUTEX(recent_mutex); #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_dir; @@ -166,8 +166,8 @@ static void recent_table_flush(struct re static int ipt_recent_match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, - const struct xt_match *match, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + const void *matchinfo, + int offset, int *hotdrop) { const struct ipt_recent_info *info = matchinfo; struct recent_table *t; @@ -233,13 +233,14 @@ out: } static int -ipt_recent_checkentry(const char *tablename, const void *ip, - const struct xt_match *match, void *matchinfo, +ipt_recent_checkentry(const char *tablename, const struct ipt_ip *ip, + void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { const struct ipt_recent_info *info = matchinfo; struct recent_table *t; unsigned i; + unsigned tlen = sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size; int ret = 0; if (hweight8(info->check_set & @@ -253,7 +254,7 @@ ipt_recent_checkentry(const char *tablen strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN) return 0; - mutex_lock(&recent_mutex); + down(&recent_mutex); t = recent_table_lookup(info->name); if (t != NULL) { t->refcnt++; @@ -261,10 +262,10 @@ ipt_recent_checkentry(const char *tablen goto out; } - t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, - GFP_KERNEL); + t = kmalloc(tlen, GFP_KERNEL); if (t == NULL) goto out; + memset(t, 0, tlen); t->refcnt = 1; strcpy(t->name, info->name); INIT_LIST_HEAD(&t->lru_list); @@ -284,18 +285,18 @@ ipt_recent_checkentry(const char *tablen spin_unlock_bh(&recent_lock); ret = 1; out: - mutex_unlock(&recent_mutex); + up(&recent_mutex); return ret; } static void -ipt_recent_destroy(const struct xt_match *match, void *matchinfo, +ipt_recent_destroy(void *matchinfo, unsigned int matchsize) { const struct ipt_recent_info *info = matchinfo; struct recent_table *t; - mutex_lock(&recent_mutex); + down(&recent_mutex); t = recent_table_lookup(info->name); if (--t->refcnt == 0) { spin_lock_bh(&recent_lock); @@ -307,7 +308,7 @@ ipt_recent_destroy(const struct xt_match #endif kfree(t); } - mutex_unlock(&recent_mutex); + up(&recent_mutex); } #ifdef CONFIG_PROC_FS @@ -383,9 +384,10 @@ static int recent_seq_open(struct inode struct recent_iter_state *st; int ret; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) return -ENOMEM; + memset(st, 0, sizeof(*st)); ret = seq_open(file, &recent_seq_ops); if (ret) kfree(st); @@ -462,7 +464,6 @@ static struct file_operations recent_fop static struct ipt_match recent_match = { .name = "recent", .match = ipt_recent_match, - .matchsize = sizeof(struct ipt_recent_info), .checkentry = ipt_recent_checkentry, .destroy = ipt_recent_destroy, .me = THIS_MODULE,