[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#332231: Backport of ipt_recent.c



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,

Reply to: