[netfilter-cvslog] r3789 - branches/netfilter-ha/linux-2.6-actact/ct_sync

laforge at netfilter.org laforge at netfilter.org
Sat Mar 12 10:51:38 CET 2005


Author: laforge at netfilter.org
Date: 2005-03-12 10:51:38 +0100 (Sat, 12 Mar 2005)
New Revision: 3789

Modified:
   branches/netfilter-ha/linux-2.6-actact/ct_sync/ct_sync_main.c
Log:
- make cmarkbit an attribute of the individual instance
- reactivate some of the (incomplete) expect synchronization
- fix locking of ct_sync_instance_list


Modified: branches/netfilter-ha/linux-2.6-actact/ct_sync/ct_sync_main.c
===================================================================
--- branches/netfilter-ha/linux-2.6-actact/ct_sync/ct_sync_main.c	2005-03-12 09:50:18 UTC (rev 3788)
+++ branches/netfilter-ha/linux-2.6-actact/ct_sync/ct_sync_main.c	2005-03-12 09:51:38 UTC (rev 3789)
@@ -66,7 +66,7 @@
 #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
 #include <linux/netfilter_ipv4/listhelp.h>
 
-#define CT_SYNC_VERSION	"0.6.51"
+#define CT_SYNC_VERSION	"0.6.52"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("KOVACS Krisztian <hidden at sch.bme.hu>, Harald Welte <laforge at netfilter.org>");
@@ -78,11 +78,6 @@
 static int notrack = 1;
 module_param(notrack, int, 0000);
 
-#ifdef CONFIG_IP_NF_CONNTRACK_MARK
-static int cmarkbit = sizeof(unsigned long) * 8 - 1;
-module_param(cmarkbit, int, 0000);
-#endif
-
 /* thread wait queue heads */
 static DECLARE_WAIT_QUEUE_HEAD(ct_sync_rcv_wait);
 
@@ -115,6 +110,9 @@
 		char syncdev[IFNAMSIZ];		/* sync device */
 		unsigned long send_burst;
 		unsigned long recv_burst;
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+		unsigned long cmarkbit;
+#endif
 	} config;
 	
 	unsigned int syncdev_ifindex;		/* ifindex for fast lookup */
@@ -133,18 +131,20 @@
 	struct cts_inst_attribute addr_attr;
 	struct cts_inst_attribute active_attr;
 	struct cts_inst_attribute syncdev_attr;
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+	struct cts_inst_attribute cmarkbit_attr;
+#endif
 	struct cts_inst_attribute sendburst_attr;
 	struct cts_inst_attribute recvburst_attr;
 };
 
 static LIST_HEAD(ct_sync_instances);
-static spinlock_t ctsync_lock = SPIN_LOCK_UNLOCKED;
+static rwlock_t ctsync_lock = RW_LOCK_UNLOCKED;
 
 /***********************************************************************
  * FILLING CTSYNC MESSAGES WITH DATA
  ***********************************************************************/
 
-#if 0
 static int
 fill_expectmsg(void *buff, __u8 event,
 	       struct ip_conntrack *master,
@@ -184,7 +184,6 @@
 
 	return 0;
 }
-#endif
 
 static int
 fill_ctmsg(void *buff, __u8 event, struct ip_conntrack *ct, __u8 flags)
@@ -505,7 +504,8 @@
 
 static inline int
 _stop_ct_timer(const struct ip_conntrack_tuple_hash *h, 
-		unsigned int *num, unsigned int *stopped)
+		unsigned int *num, unsigned int *stopped,
+		struct ct_sync_instance *ctsi)
 {
 	struct ip_conntrack *ct = h->ctrack;
 
@@ -516,7 +516,7 @@
 	if (is_confirmed(ct)
 #ifdef CONFIG_IP_NF_CONNTRACK_MARK
 	    /* stop timer only if this is a synchronized connection */
-	    && test_bit(cmarkbit, &ct->mark)
+	    && test_bit(ctsi->config.cmarkbit, &ct->mark)
 #endif
 	) {
 		if (del_timer(&ct->timeout))
@@ -527,7 +527,7 @@
 }
 
 static void
-ct_sync_stop_timers(void)
+ct_sync_stop_timers(struct ct_sync_instance *ctsi)
 {
 	int i;
 	unsigned int num_entries = 0;
@@ -540,7 +540,7 @@
 	for (i = 0; i < ip_conntrack_htable_size; i++) {
 		if (LIST_FIND(&ip_conntrack_hash[i], _stop_ct_timer,
 			      struct ip_conntrack_tuple_hash *,
-			      &num_entries, &num_stopped))
+			      &num_entries, &num_stopped, ctsi))
 			break;
 	}
 
@@ -651,7 +651,9 @@
 static int
 ct_sync_msg_process_updateexpect(void *data, u16 len)
 {
+#if 0
 	struct ct_sync_expect *exp = (struct ct_sync_expect *)data;
+#endif
 
 	CT_SYNC_ENTER();
 
@@ -694,8 +696,8 @@
 		__unexpect_related(exp);
 
 unlock_out:
-	WRITE_INLOCK(&ip_conntrack_expect_tuple_lock);
-	READ_UNLOCK(&ip_donntrack_lock);
+	WRITE_UNLOCK(&ip_conntrack_expect_tuple_lock);
+	READ_UNLOCK(&ip_conntrack_lock);
 #endif
 	CT_SYNC_LEAVE();
 	return 0;
@@ -980,6 +982,8 @@
 	        struct cts_protoh *cph)
 {
 	struct ip_conntrack *ct = h->ctrack;
+	struct ct_sync_instance *ctsi = 
+			container_of(cph, struct ct_sync_instance, protoh);
 
 	if (DIRECTION(h))
 		return 0;
@@ -987,7 +991,7 @@
 	if (likely(is_confirmed(ct)
 #ifdef CONFIG_IP_NF_CONNTRACK_MARK
 	    /* send only if this is a synchronized connection */
-	    && test_bit(cmarkbit, &ct->mark)
+	    && test_bit(ctsi->config.cmarkbit, &ct->mark)
 #endif
 	    )) {
 		char *buff;
@@ -1155,12 +1159,13 @@
 	if (!is_confirmed(ct))
 		return;
 
+	read_lock(&ctsync_lock);
 	list_for_each_entry(ctsi, &ct_sync_instances, list) {
 
 		if (cts_proto_is_master(ctsi->protoh) 
 #ifdef CONFIG_IP_NF_CONNTRACK_MARK
 			   /* generate a message only if the conntrack is synchronized */
-			   && test_bit(cmarkbit, &ct->mark)
+			   && test_bit(ctsi->config.cmarkbit, &ct->mark)
 #endif
 		) {
 			unsigned char *buff;
@@ -1171,14 +1176,14 @@
 					CTMSG_SIZEOF(struct ct_sync_conntrack));
 			if (unlikely(!buff)) {
 				CT_SYNC_ERR("unable to store create event\n");
-				CT_SYNC_LEAVE();
-				return;
+				continue;
 			}
 			fill_ctmsg(buff, CT_SYNC_MSG_UPDATE, ct, 
 				   new ? CTS_UPD_F_NEW : 0);
 			csb_use_dec(ctsi->protoh, csb);
 		}
 	}
+	read_unlock(&ctsync_lock);
 
 	CT_SYNC_LEAVE();
 }
@@ -1195,12 +1200,13 @@
 	if (!is_confirmed(ct))
 		return;
 
+	read_lock(&ctsync_lock);
 	list_for_each_entry(ctsi, &ct_sync_instances, list) {
 		if (cts_proto_is_master(ctsi->protoh) 
 #ifdef CONFIG_IP_NF_CONNTRACK_MARK
 			   /* generate a message only if the conntrack is to be
 			    * synchronized */
-			   && test_bit(cmarkbit, &ct->mark)
+			   && test_bit(ctsi->config.cmarkbit, &ct->mark)
 #endif
 		) {
 			unsigned char *buff;
@@ -1213,8 +1219,7 @@
 					CTMSG_SIZEOF(*t));
 			if (unlikely(!buff)) {
 				CT_SYNC_ERR("unable to store destroy event\n");
-				CT_SYNC_LEAVE();
-				return;
+				continue;
 			}
 			hdr = (struct ct_sync_msghdr *) buff;
 			t = (void *)hdr + sizeof(*hdr);
@@ -1230,69 +1235,79 @@
 			csb_use_dec(ctsi->protoh, csb);
 		}
 	}
+	read_unlock(&ctsync_lock);
 	
 	CT_SYNC_LEAVE();
 }
 
-#if 0
 /* conntrack expectation created notification */
 static void
 ct_sync_expect_create(struct ip_conntrack_expect *exp)
 {
+	struct ct_sync_instance *ctsi;
 	struct cts_buff *csb;
 	struct ip_conntrack *master_ct = exp->expectant;
 
 	CT_SYNC_ENTER();
 
-	if (likely(cts_proto_is_master(cts_cfg.protoh) &&
-	           is_confirmed(master_ct))) {
-		void *buff;
+	read_lock(&ctsync_lock);
+	list_for_each_entry(ctsi, &ct_sync_instances, list) {
+		if (likely(cts_proto_is_master(ctsi->protoh)
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+		    && test_bit(ctsi->config.cmarkbit, &master_ct->mark)
+#endif
+		    && is_confirmed(master_ct))) {
+			void *buff;
 
-		buff = cts_proto_want_enqueue(cts_cfg.protoh, &csb,
-				CTMSG_SIZEOF(struct ct_sync_expect));
-		if (unlikely(!buff)) {
-			CT_SYNC_ERR("unable to enqueue event\n");
-			CT_SYNC_LEAVE();
-			return;
+			buff = cts_proto_want_enqueue(ctsi->protoh, &csb,
+					CTMSG_SIZEOF(struct ct_sync_expect));
+			if (unlikely(!buff)) {
+				CT_SYNC_ERR("unable to enqueue event\n");
+				continue;
+			}
+			fill_expectmsg(buff, CT_SYNC_MSG_UPDATE, master_ct, 
+					exp);
+			csb_use_dec(ctsi->protoh, csb);
 		}
-		fill_expectmsg(buff, CT_SYNC_MSG_UPDATE, master_ct, exp);
-		csb_use_dec(cts_cfg.protoh, csb);
 	}
+	read_unlock(&ctsync_lock);
 
 	CT_SYNC_LEAVE();
-
-	return;
 }
 
 /* conntrack expectation destroyed notification */
 static void
 ct_sync_expect_destroy(struct ip_conntrack_expect *exp)
 {
+	struct ct_sync_instance *ctsi;
 	struct cts_buff *csb;
 	struct ip_conntrack *master_ct = exp->expectant;
 
 	CT_SYNC_ENTER();
 
-	if (likely(cts_proto_is_master(cts_cfg.protoh) &&
-	    	   is_confirmed(master_ct))) {
-		void *buff;
-
-		buff = cts_proto_want_enqueue(cts_cfg.protoh, &csb, 
-				CTMSG_SIZEOF(struct ct_sync_expect));
-		if (unlikely(!buff)) {
-			CT_SYNC_ERR("unable to enqueue event\n");
-			CT_SYNC_LEAVE();
-			return;
+	read_lock(&ctsync_lock);
+	list_for_each_entry(ctsi, &ct_sync_instances, list) {
+		if (likely(cts_proto_is_master(ctsi->protoh) 
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+		    && test_bit(ctsi->config.cmarkbit, &master_ct->mark)
+#endif
+		    && is_confirmed(master_ct))) {
+			void *buff;
+	
+			buff = cts_proto_want_enqueue(ctsi->protoh, &csb, 
+					CTMSG_SIZEOF(struct ct_sync_expect));
+			if (unlikely(!buff)) {
+				CT_SYNC_ERR("unable to enqueue event\n");
+				continue;
+			}
+			// FIXME: implementation
+			csb_use_dec(ctsi->protoh, csb);
 		}
-		// FIXME: implementation
-		csb_use_dec(cts_cfg.protoh, csb);
 	}
+	read_unlock(&ctsync_lock);
 
 	CT_SYNC_LEAVE();
-
-	return;
 }
-#endif
 
 static int
 ct_sync_notify(struct notifier_block *this,
@@ -1356,6 +1371,7 @@
 
 	/* all traffic coming in or going out sync interface is not
 	   to be tracked. Also, loopback traffic is ignored */
+	read_lock(&ctsync_lock);
 	list_for_each_entry(ctsi, &ct_sync_instances, list) {
 		if (ctsi->syncdev_ifindex == ifindex ||
 		    loopback_dev.ifindex == ifindex) {
@@ -1363,9 +1379,10 @@
 			(*pskb)->nfct = &ip_conntrack_untracked.ct_general;
 			(*pskb)->nfctinfo = IP_CT_NEW;
 			nf_conntrack_get((*pskb)->nfct);
-			return NF_ACCEPT;
+			break;
 		}
 	}
+	read_unlock(&ctsync_lock);
 
 	return NF_ACCEPT;
 }
@@ -1392,18 +1409,23 @@
 	else
 		return NF_ACCEPT;
 	
+	read_lock(&ctsync_lock);
 	list_for_each_entry(ctsi, &ct_sync_instances, list) {
-		if (cts_proto_is_master(ctsi->protoh))
+		if (cts_proto_is_master(ctsi->protoh)) {
 			/* if we have one instance in master,
 			 * we need to accept all packets */
+			read_unlock(&ctsync_lock);
 			return NF_ACCEPT;
-		else {
+		} else {
 			/* if we have one instance in slave mode, all traffic
 			 * on sync interface has to be accepted */
-			if (ifindex == ctsi->syncdev_ifindex)
+			if (ifindex == ctsi->syncdev_ifindex) {
+				read_unlock(&ctsync_lock);
 				return NF_ACCEPT;
+			}
 		}
 	}
+	read_unlock(&ctsync_lock);
 
 	/* drop is the default */
 	return NF_DROP;
@@ -1458,7 +1480,9 @@
 		} else if (oldstate >= CT_SYNC_PSTATE_MASTER_INIT) {
 			/* transition from master to slave */
 			ip_conntrack_unregister_notifier(&ct_sync_notifier);
-			ct_sync_stop_timers();
+			ct_sync_stop_timers(
+				container_of(cph, struct ct_sync_instance, 
+					     protoh));
 		}
 		break;
 
@@ -1794,6 +1818,25 @@
 	return len;
 }
 
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+static ssize_t sysfs_cmarkbit_show(struct ct_sync_instance *ctsi,
+				   char *buf)
+{
+	sprintf(buf, "%lu\n", ctsi->config.cmarkbit);
+	return strlen(buf);
+}
+
+static ssize_t sysfs_cmarkbit_store(struct ct_sync_instance *ctsi,
+				    const char *buf, size_t len)
+{
+	if (ctsi->active != 0)
+		return -EBUSY;
+
+	ctsi->config.cmarkbit = simple_strtoul(buf, NULL, 10);
+	return len;
+}
+#endif
+
 /* create a new instance by writing it's name to this file */
 static ssize_t sysfs_control_store(struct ct_sync_instance *ctsi,
 				  const char *buf, size_t len)
@@ -1926,10 +1969,9 @@
 	ctsi->config.addr.ss_family = AF_INET;
 	strlcpy(ctsi->config.name, name, MAXNAMELEN);
 
-	spin_lock(&ctsync_lock);
+	write_lock(&ctsync_lock);
 	if (__cts_instance_find(name)) {
 		ret = -EEXIST;
-		spin_unlock(&ctsync_lock);
 		goto out_unlock;
 	}
 
@@ -1986,10 +2028,16 @@
 	if (ret < 0)
 		goto out_sysfs_sendburst;
 
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+	CTSI_ATTR_INIT(ctsi->cmarkbit_attr, "cmarkbit", 0640,
+			sysfs_cmarkbit_show, sysfs_cmarkbit_store);
+	ret = sysfs_create_file(&ctsi->kobj, &ctsi->cmarkbit_attr.attr);
+	if (ret < 0)
+		goto out_sysfs_recvburst;
+#endif
 
-
 	list_add(&ctsi->list, &ct_sync_instances);
-	spin_unlock(&ctsync_lock);
+	write_unlock(&ctsync_lock);
 
 out:
 	CT_SYNC_LEAVE();
@@ -2010,7 +2058,7 @@
 out_kobj:
 	kobject_unregister(&ctsi->kobj);
 out_unlock:
-	spin_unlock(&ctsync_lock);
+	write_unlock(&ctsync_lock);
 out_free:
 	kfree(ctsi);
 	goto out;
@@ -2089,7 +2137,7 @@
 
 	CT_SYNC_ENTER();
 
-	spin_lock(&ctsync_lock);
+	write_lock(&ctsync_lock);
 	ctsi = __cts_instance_find(name);
 	if (!ctsi) {
 		ret = -EINVAL;
@@ -2115,7 +2163,7 @@
 	kfree(ctsi);
 
 out_unlock:
-	spin_unlock(&ctsync_lock);
+	write_unlock(&ctsync_lock);
 
 	CT_SYNC_LEAVE();
 	return ret;
@@ -2132,8 +2180,6 @@
 	return 1;
 }
 
-static struct task_struct *rcv_thread, *send_thread, *initsync_thread;
-
 /* DO NOT declare this as __init!! */
 static int
 init_or_cleanup(int fini)
@@ -2155,9 +2201,6 @@
 			sizeof(struct ct_sync_pkthdr));
 	CT_SYNC_DEBUG("ct_sync_msghdr: %d bytes\n", 
 			sizeof(struct ct_sync_msghdr));
-#ifdef CONFIG_IP_NF_CONNTRACK_MARK
-	CT_SYNC_DEBUG("cmarkbit: %d\n", cmarkbit);
-#endif
 
 	/* Register hooks first, make sure not even the first sync packet gets
 	 * tracked */
@@ -2199,13 +2242,7 @@
 	printk(KERN_NOTICE "netfilter conntrack_sync version %s loaded\n",
 	       CT_SYNC_VERSION);
 	CT_SYNC_INFO("parameters: l2drop=%u notrack=%u"
-#ifdef CONFIG_IP_NF_CONNTRACK_MARK
-		     " cmarkbit=%u"
-#endif
 		     "\n", l2drop, notrack
-#ifdef CONFIG_IP_NF_CONNTRACK_MARK
-		     , cmarkbit
-#endif
 		     );
 
         return 0;
@@ -2217,10 +2254,12 @@
 	{
 	struct ct_sync_instance *ctsi, *tmp;
 	CT_SYNC_DEBUG("deactivating/destroying all instances\n");
+	read_lock(&ctsync_lock);
 	list_for_each_entry_safe(ctsi, tmp, &ct_sync_instances, list) {
 		cts_instance_deactivate(ctsi);
 		cts_instance_destroy(ctsi->config.name);
 	}
+	read_unlock(&ctsync_lock);
 	}
 
 	nf_kset_unregister(&cts_instance_kset);




More information about the netfilter-cvslog mailing list