[PATCH 8/8] Netfilter: Use ct_extend for number of expectations

Rusty Russell rusty at rustcorp.com.au
Wed Jan 12 21:59:41 CET 2005


Name: Use ct_extend for number of expectations
Status: Tested lightly under nfsim
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

Only connections with helpers can have expectations, so the
"expectations" field is usually unused.  Put it in CTE_CT_HELPER with
the helper pointer.

Index: linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ip_conntrack_standalone.c
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-01-12 23:42:01.974639936 +1100
+++ linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-01-12 23:45:27.310424152 +1100
@@ -386,13 +386,13 @@
 	/* This is where we call the helper: as the packet goes out. */
 	ct = ip_conntrack_get(*pskb, &ctinfo);
 	if (ct) {
-		struct ip_conntrack_helper **helpp;
+		struct ip_ct_helper_extend *helpext;
 
 		/* Don't need lock: ct not in hash yet. */
-		helpp = ct_extend_find(ct->ext, CTE_CT_HELPER);
-		if (helpp) {
+		helpext = ct_extend_find(ct->ext, CTE_CT_HELPER);
+		if (helpext) {
 			unsigned int ret;
-			ret = (*helpp)->help(pskb, ct, ctinfo);
+			ret = helpext->helper->help(pskb, ct, ctinfo);
 			if (ret != NF_ACCEPT)
 				return ret;
 		}
Index: linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ip_conntrack.h
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/include/linux/netfilter_ipv4/ip_conntrack.h	2005-01-12 23:44:23.300155192 +1100
+++ linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ip_conntrack.h	2005-01-12 23:45:27.312423848 +1100
@@ -166,8 +166,6 @@
 	/* Accounting Information (same cache line as other written members) */
 	struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
 #endif
-	/* Current number of expected connections */
-	unsigned int expecting;
 
 	/* Storage reserved for other modules: */
 	union ip_conntrack_proto proto;
Index: linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ipt_helper.c
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/net/ipv4/netfilter/ipt_helper.c	2005-01-12 23:44:23.301155040 +1100
+++ linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ipt_helper.c	2005-01-12 23:45:27.312423848 +1100
@@ -41,7 +41,7 @@
 	const struct ipt_helper_info *info = matchinfo;
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack_helper **helpp;
+	struct ip_ct_helper_extend *helpext;
 	struct ip_conntrack **master;
 	int ret = info->invert;
 	
@@ -58,21 +58,21 @@
 	}
 
 	READ_LOCK(&ip_conntrack_lock);
-	helpp = ct_extend_find((*master)->ext, CTE_CT_HELPER);
-	if (!helpp) {
+	helpext = ct_extend_find((*master)->ext, CTE_CT_HELPER);
+	if (!helpext) {
 		DEBUGP("ipt_helper: master ct %p has no helper\n", 
 			exp->expectant);
 		goto out_unlock;
 	}
 
 	DEBUGP("master's name = %s , info->name = %s\n", 
-		(*helpp)->name, info->name);
+		helpext->helper->name, info->name);
 
 	if (info->name[0] == '\0')
 		ret ^= 1;
 	else
-		ret ^= !strncmp((*helpp)->name, info->name, 
-		                strlen((*helpp)->name));
+		ret ^= !strncmp(helpext->helper->name, info->name, 
+		                strlen(helpext->helper->name));
 out_unlock:
 	READ_UNLOCK(&ip_conntrack_lock);
 	return ret;
Index: linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ct_extend.h
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/include/linux/netfilter_ipv4/ct_extend.h	2005-01-12 23:45:24.353873616 +1100
+++ linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ct_extend.h	2005-01-12 23:46:34.107269488 +1100
@@ -16,7 +16,7 @@
 #define CTE_MASQ_TYPE char 	/* Actually char[IFNAMSIZ] */
 #define CTE_FTP_CONN_TYPE struct ip_ct_ftp_master
 #define CTE_MARK_TYPE unsigned long
-#define CTE_CT_HELPER_TYPE struct ip_conntrack_helper *
+#define CTE_CT_HELPER_TYPE struct ip_ct_helper_extend
 #define CTE_NAT_SEQ_TYPE struct ip_nat_seq
 #define CTE_MASTER_TYPE struct ip_conntrack *
 
Index: linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ip_conntrack_helper.h
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/include/linux/netfilter_ipv4/ip_conntrack_helper.h	2005-01-12 23:28:49.949046128 +1100
+++ linux-2.6.10-bk14-Netfilter/include/linux/netfilter_ipv4/ip_conntrack_helper.h	2005-01-12 23:45:27.313423696 +1100
@@ -26,6 +26,15 @@
 		    enum ip_conntrack_info conntrackinfo);
 };
 
+/* The structure for CTE_CT_HELPER */
+struct ip_ct_helper_extend
+{
+	struct ip_conntrack_helper *helper;
+
+	/* Current number of expected connections */
+	unsigned int expecting;
+};
+
 extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
 extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
 
Index: linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ip_conntrack_core.c
===================================================================
--- linux-2.6.10-bk14-Netfilter.orig/net/ipv4/netfilter/ip_conntrack_core.c	2005-01-12 23:44:23.304154584 +1100
+++ linux-2.6.10-bk14-Netfilter/net/ipv4/netfilter/ip_conntrack_core.c	2005-01-12 23:45:27.316423240 +1100
@@ -148,10 +148,12 @@
 
 static void unlink_expect(struct ip_conntrack_expect *exp)
 {
+	struct ip_ct_helper_extend *helpext;
 	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
 	list_del(&exp->list);
+	helpext = ct_extend_find(exp->master->ext, CTE_CT_HELPER);
 	/* Logically in destroy_expect, but we hold the lock here. */
-	exp->master->expecting--;
+	helpext->expecting--;
 }
 
 static void expectation_timed_out(unsigned long ul_expect)
@@ -193,7 +195,7 @@
 	struct ip_conntrack_expect *i, *tmp;
 
 	/* Optimization: most connection never expect any others. */
-	if (ct->expecting == 0)
+	if (!ct_extend_find(ct->ext, CTE_CT_HELPER))
 		return;
 
 	list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
@@ -585,18 +587,20 @@
 		nf_conntrack_get(&exp->master->ct_general);
 		CONNTRACK_STAT_INC(expect_new);
 	} else {
-		struct ip_conntrack_helper *helper, **helpp;
+		struct ip_conntrack_helper *helper;
+		struct ip_ct_helper_extend *helpext;
 
 		helper = ip_ct_find_helper(&repl_tuple);
 		if (helper) {
-			helpp = ct_extend_add(&conntrack->ext, CTE_CT_HELPER,
-					      GFP_ATOMIC);
-			if (!helpp) {
+			helpext = ct_extend_add(&conntrack->ext, CTE_CT_HELPER,
+						GFP_ATOMIC);
+			if (!helpext) {
 				kmem_cache_free(ip_conntrack_cachep,conntrack);
 				WRITE_UNLOCK(&ip_conntrack_lock);
 				return NULL;
 			}
-			*helpp = helper;
+			helpext->helper = helper;
+			helpext->expecting = 0;
 		}
 		CONNTRACK_STAT_INC(new);
 	}
@@ -828,18 +832,18 @@
 }
 
 static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp,
-				       struct ip_conntrack_helper *helper)
+				       struct ip_ct_helper_extend *helpext)
 {
 	atomic_inc(&exp->master->ct_general.use);
-	exp->master->expecting++;
+	helpext->expecting++;
 	list_add(&exp->list, &ip_conntrack_expect_list);
 
-	if (helper->timeout) {
+	if (helpext->helper->timeout) {
 		init_timer(&exp->timeout);
 		exp->timeout.data = (unsigned long)exp;
 		exp->timeout.function = expectation_timed_out;
 		exp->timeout.expires
-			= jiffies + helper->timeout * HZ;
+			= jiffies + helpext->helper->timeout * HZ;
 		add_timer(&exp->timeout);
 	} else
 		exp->timeout.function = NULL;
@@ -878,20 +882,20 @@
 {
 	struct ip_conntrack_expect *i;
 	int ret;
-	struct ip_conntrack_helper **helpp;
+	struct ip_ct_helper_extend *helpext;
 
 	DEBUGP("ip_conntrack_expect_related %p\n", related_to);
 	DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
 	DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);
 
 	WRITE_LOCK(&ip_conntrack_lock);
-	helpp = ct_extend_find(expect->master->ext, CTE_CT_HELPER);
-	BUG_ON(!helpp || !*helpp);
+	helpext = ct_extend_find(expect->master->ext, CTE_CT_HELPER);
+	BUG_ON(!helpext || !helpext->helper);
 
 	list_for_each_entry(i, &ip_conntrack_expect_list, list) {
 		if (expect_matches(i, expect)) {
 			/* Refresh timer: if it's dying, ignore.. */
-			if (refresh_timer(i, *helpp)) {
+			if (refresh_timer(i, helpext->helper)) {
 				ret = 0;
 				/* We don't need the one they've given us. */
 				ip_conntrack_expect_free(expect);
@@ -904,11 +908,11 @@
 	}
 
 	/* Will be over limit? */
-	if ((*helpp)->max_expected && 
-	    expect->master->expecting >= (*helpp)->max_expected)
+	if (helpext->helper->max_expected && 
+	    helpext->expecting >= helpext->helper->max_expected)
 		evict_oldest_expect(expect->master);
 
-	ip_conntrack_expect_insert(expect, *helpp);
+	ip_conntrack_expect_insert(expect, helpext);
 	ret = 0;
 out:
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -920,7 +924,7 @@
 int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
 			     const struct ip_conntrack_tuple *newreply)
 {
-	struct ip_conntrack_helper *helper, **helpp;
+	struct ip_conntrack_helper *helper;
 
 	/* Should be unconfirmed, so not in hash table yet */
 	IP_NF_ASSERT(!is_confirmed(conntrack));
@@ -929,22 +933,28 @@
 	DUMP_TUPLE(newreply);
 
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
-	if (conntrack->expecting || ct_extend_find(conntrack->ext, CTE_MASTER))
+	if (ct_extend_find(conntrack->ext, CTE_MASTER))
 		return 0;
 
 	WRITE_LOCK(&ip_conntrack_lock);
 	helper = ip_ct_find_helper(newreply);
 	if (helper) {
-		helpp = ct_extend_find(conntrack->ext, CTE_CT_HELPER);
-		if (!helpp) {
-			helpp = ct_extend_add(&conntrack->ext, CTE_CT_HELPER,
-					      GFP_ATOMIC);
-			if (!helpp) {
-				READ_UNLOCK(&ip_conntrack_lock);
+		struct ip_ct_helper_extend *helpext;
+
+		helpext = ct_extend_find(conntrack->ext, CTE_CT_HELPER);
+		if (helpext->expecting) {
+			WRITE_UNLOCK(&ip_conntrack_lock);
+			return 0;
+		}
+		if (!helpext) {
+			helpext = ct_extend_add(&conntrack->ext, CTE_CT_HELPER,
+						GFP_ATOMIC);
+			if (!helpext) {
+				WRITE_UNLOCK(&ip_conntrack_lock);
 				return -ENOMEM;
 			}
 		}
-		*helpp = helper;
+		helpext->helper = helper;
 	}
 	WRITE_UNLOCK(&ip_conntrack_lock);
 	return 0;
@@ -963,10 +973,10 @@
 static inline int unhelp(struct ip_conntrack_tuple_hash *i,
 			 const struct ip_conntrack_helper *me)
 {
-	struct ip_conntrack_helper **helpp;
-	helpp = ct_extend_find(tuplehash_to_ctrack(i)->ext, CTE_CT_HELPER);
+	struct ip_ct_helper_extend *helpext;
+	helpext = ct_extend_find(tuplehash_to_ctrack(i)->ext, CTE_CT_HELPER);
 
-	if (helpp && *helpp == me)
+	if (helpext && helpext->helper == me)
 		tuplehash_to_ctrack(i)->ext
 			= ct_extend_del(tuplehash_to_ctrack(i)->ext,
 					CTE_CT_HELPER);
@@ -984,10 +994,10 @@
 
 	/* Get rid of expectations */
 	list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
-		struct ip_conntrack_helper **helpp;
-		helpp = ct_extend_find(exp->master->ext, CTE_CT_HELPER);
+		struct ip_ct_helper_extend *helpext;
+		helpext = ct_extend_find(exp->master->ext, CTE_CT_HELPER);
 
-		if (*helpp == me && del_timer(&exp->timeout)) {
+		if (helpext->helper == me && del_timer(&exp->timeout)) {
 			unlink_expect(exp);
 			destroy_expect(exp);
 		}
@@ -1233,8 +1243,8 @@
 
 static struct ct_extend_type helper_extend =
 {
-	.len = sizeof(struct ip_conntrack_helper *),
-	.align = __alignof__(struct ip_conntrack_helper *),
+	.len = sizeof(struct ip_ct_helper_extend),
+	.align = __alignof__(struct ip_ct_helper_extend),
 	.type = CTE_CT_HELPER,
 };
 




More information about the netfilter-devel mailing list