[netfilter-cvslog] r3597 - branches/netfilter-ha/linux-2.6/ct_sync

hidden at netfilter.org hidden at netfilter.org
Thu Jan 13 00:04:56 CET 2005


Author: hidden at netfilter.org
Date: 2005-01-13 00:04:55 +0100 (Thu, 13 Jan 2005)
New Revision: 3597

Modified:
   branches/netfilter-ha/linux-2.6/ct_sync/ct_sync_main.c
Log:
Revision: hidden at sch.bme.hu--2005-public/netfilter-ha--mainline--1.0--patch-19

Rework conntrack entry update function.

* ct_sync/ct_sync_main.c (_ct_sync_update_conntrack): reorganized
  conntrack entry updating, now initial update and further updates are
  clearly separated


Modified: branches/netfilter-ha/linux-2.6/ct_sync/ct_sync_main.c
===================================================================
--- branches/netfilter-ha/linux-2.6/ct_sync/ct_sync_main.c	2005-01-12 23:04:50 UTC (rev 3596)
+++ branches/netfilter-ha/linux-2.6/ct_sync/ct_sync_main.c	2005-01-12 23:04:55 UTC (rev 3597)
@@ -244,101 +244,100 @@
 _ct_sync_update_conntrack(struct ip_conntrack *ct,
 			  struct ct_sync_conntrack *sct, int new)
 {
-	struct ip_conntrack_helper *helper;
-	int previous_nat_initialized = 0;
-#ifdef CONFIG_IP_NF_TARGET_MASQUERADE
-	struct net_device *masq_dev;
-#endif
-
 	CT_SYNC_ENTER();
 
-	/* fill tuples for new conntracks, tuples must not be changed
-	 * for confirmed connections */
-	if (new) {
-		memcpy(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, &sct->orig,
-		       sizeof(struct ip_conntrack_tuple));
-		memcpy(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, &sct->reply,
-		       sizeof(struct ip_conntrack_tuple));
-	} else {
+	if (likely(!new)) {
+		/* check if the conntrack entry already has an active timer:
+		 * it is possible that we try to update an active entry, which
+		 * we must avoid */
+		if (timer_pending(&ct->timeout)) {
+			CT_SYNC_DEBUG("Trying to update an active conntrack entry!\n");
+			CT_SYNC_LEAVE();
+			return -1;
+		}
+
 		CT_SYNC_ASSERT(memcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
-				    &sct->orig, sizeof(sct->orig)) == 0);
+				      &sct->orig, sizeof(sct->orig)) == 0);
 		CT_SYNC_ASSERT(memcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
-				    &sct->reply, sizeof(sct->reply)) == 0);
-		CT_SYNC_DUMP_TUPLE(&sct->orig);
-		CT_SYNC_DUMP_TUPLE(&sct->reply);
-	}
+				      &sct->reply, sizeof(sct->reply)) == 0);
 
-	CT_SYNC_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	CT_SYNC_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-
-	/* timeout */
-	if (!timer_pending(&ct->timeout)) {
+		/* we should proceed with the update. only parts of an existing
+		 * (confirmed) entry can be updated:
+		 *   - status
+		 *   - timeout (the timer is _inactive_)
+		 *   - proto
+		 *   - help (if a conntrack helper is present)
+		 *   - mark
+		 *   - nat.help (if there is a nat helper)
+		 */
+		ct->status = sct->status;
 		ct->timeout.expires = sct->expires;
+		memcpy(&ct->proto, &sct->proto, sizeof(ct->proto));
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+		ct->mark = (unsigned long) sct->mark;
+#endif
+		/* if conntrack has a helper, update helper info */
+		if (ct->helper)
+			memcpy(&ct->help, &sct->help, sizeof(ct->help));
+		/* if there is a nat helper present, update helper info */
+		if (sct->nat_initialized && ct->nat.info.initialized &&
+		    ct->nat.info.helper)
+			memcpy(&ct->nat.help, &sct->nat_help, sizeof(ct->nat.help));
 	} else {
-		CT_SYNC_DEBUG("Trying to update an active conntrack entry!\n");
-		CT_SYNC_LEAVE();
-		return -1;
-	}
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+		struct ip_nat_info *nat = &ct->nat.info;
+#endif
 
-	/* status */
-	ct->status = sct->status;
+		/* this is a new entry, fill in everything */
+		ct->status = sct->status;
+		ct->timeout.expires = sct->expires;
+		ct->expecting = 0;
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+		ct->mark = (unsigned long) sct->mark;
+#endif
+		memcpy(&ct->proto, &sct->proto, sizeof(ct->proto));
 
-	/* sibling_list initialized by conntrack_alloc */
+		memcpy(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, &sct->orig,
+		       sizeof(struct ip_conntrack_tuple));
+		memcpy(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, &sct->reply,
+		       sizeof(struct ip_conntrack_tuple));
 
-	/* FIXME: sibling expectations */
-	//ct->expecting = sct->expecting;
-	ct->expecting = 0;
+		/* conntrack helper */
+		if (unlikely(sct->helper[0] != '\0')) {
+			struct ip_conntrack_helper *helper;
 
-	/* FIXME: have to look up the master_ct by tuple and then iterate
-	 * over ip_conntrack_expect's in order to link with the correct
-	 * expect */
-
-	/* conntrack helper */
-	if (unlikely(sct->helper[0] != '\0')) {
-		sct->helper[CT_SYNC_CTHELPERSIZE - 1] = '\0';
-		READ_LOCK(&ip_conntrack_lock);
-		helper = __ip_ct_find_helper_by_name(sct->helper);
-		if (unlikely(!helper)) {
-			CT_SYNC_ERR("Unknown conntrack helper `%s', "
-				    "ignoring.\n", sct->helper);
-			ct->helper = NULL;
-		} else {
-			ct->helper = helper;
-			memcpy(&ct->help, &sct->help, sizeof(ct->help));
+			sct->helper[CT_SYNC_CTHELPERSIZE - 1] = '\0';
+			READ_LOCK(&ip_conntrack_lock);
+			helper = __ip_ct_find_helper_by_name(sct->helper);
+			if (unlikely(!helper)) {
+				CT_SYNC_ERR("Unknown conntrack helper `%s', "
+					    "ignoring.\n", sct->helper);
+				ct->helper = NULL;
+			} else {
+				ct->helper = helper;
+				memcpy(&ct->help, &sct->help, sizeof(ct->help));
+			}
+			READ_UNLOCK(&ip_conntrack_lock);
 		}
-		READ_UNLOCK(&ip_conntrack_lock);
-	}
 
-	/* protocol data */
-	memcpy(&ct->proto, &sct->proto, sizeof(ct->proto));
-
-	/* NAT */
 #ifdef CONFIG_IP_NF_NAT_NEEDED
-
-	{
-		struct ip_nat_info *nat = &ct->nat.info;
-		/* DEBUG: initialize list heads to avoid oops */
+		/* NAT */
 		INIT_LIST_HEAD(&nat->bysource);
 		INIT_LIST_HEAD(&nat->byipsproto);
-	}
 
-	//if (likely(sct->nat_initialized && sct->nat_num_manips)) {
-	if (likely(sct->nat_initialized )) {
-		struct ip_nat_info *nat = &ct->nat.info;
-		previous_nat_initialized = nat->initialized;
+		if (likely(sct->nat_initialized &&
+			   sct->nat_num_manips <= IP_NAT_MAX_MANIPS)) {
+#ifdef CONFIG_IP_NF_TARGET_MASQUERADE
+			struct net_device *masq_dev;
+#endif
 
-		/* make sure we don't modify the NAT info of an already
-		 * confirmed entry */
-		CT_SYNC_ASSERT(new || (nat->initialized == sct->nat_initialized));
-		CT_SYNC_DEBUG("NAT initialized: %x, new value %x\n", nat->initialized,
-				sct->nat_initialized);
-
-		if (new && sct->nat_initialized) {
 			nat->initialized = sct->nat_initialized;
 			/* do not set .conntrack, place_in_hashes will do */
 			nat->num_manips = sct->nat_num_manips;
 			memcpy(&nat->manips, sct->nat_manips, 
-				(sct->nat_num_manips * sizeof(struct ip_nat_info_manip)));
+			       (sct->nat_num_manips * sizeof(struct ip_nat_info_manip)));
+
+			/* NAT helper, if present */
 			if (unlikely(sct->nat_helper[0] != '\0')) {
 				struct ip_nat_helper *helper;
 				/* look up nat helper */
@@ -357,6 +356,7 @@
 				READ_UNLOCK(&ip_nat_lock);
 				memcpy(&nat->seq, &sct->nat_seq, sizeof(nat->seq));
 			}
+
 #ifdef CONFIG_IP_NF_TARGET_MASQUERADE
 			if ((masq_dev = dev_get_by_name(sct->nat_masq_iface)) != NULL) {
 				ct->nat.masq_index = masq_dev->ifindex;
@@ -367,41 +367,30 @@
 			}
 #endif
 		}
-	}
 #endif /* CONFIG_IP_NF_NAT_NEEDED */
 
-#ifdef CONFIG_IP_NF_CONNTRACK_MARK
-	ct->mark = (unsigned long) sct->mark;
-#endif
-
-	/* add to hash tables */
-	if (new && is_confirmed(ct)) {
+		/* add to hash tables */
 		WRITE_LOCK(&ip_conntrack_lock);
 		if (!__ip_conntrack_find(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL) 
 		    && !__ip_conntrack_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
-#if 0
-			/* place in ordered list */
-			ct->id = ip_conntrack_next_id++;
-			list_add_tail(&ct->olist, &ip_conntrack_ordered_list);
-#endif
 			/* put in conntrack hash */
 			__ip_conntrack_hash_insert(ct);
 			atomic_inc(&ct->ct_general.use);
 
+#ifdef CONFIG_IP_NF_NAT_NEEDED
 			/* put in NAT hashes if necessary */
-			if (sct->nat_initialized) {
-				CT_SYNC_ASSERT(previous_nat_initialized == 0);
+			if (ct->nat.info.initialized) {
 				WRITE_LOCK(&ip_nat_lock);
 				place_in_hashes(ct, &ct->nat.info);
 				WRITE_UNLOCK(&ip_nat_lock);
-			} else
-				CT_SYNC_INFO("sct->nat_initialized == 0\n");
+			}
+#endif
 
 		} else {
 			CT_SYNC_ERR("want to put conntrack in hash but is already there\n");
 		}
 		WRITE_UNLOCK(&ip_conntrack_lock);
-	}
+	} /* if (new) */
 
 	CT_SYNC_LEAVE();
 




More information about the netfilter-cvslog mailing list