[netfilter-cvslog] r6835 - in trunk/conntrack-tools: extensions include src

pablo at netfilter.org pablo at netfilter.org
Sun May 20 23:13:06 CEST 2007


Author: pablo at netfilter.org
Date: 2007-05-20 23:13:06 +0200 (Sun, 20 May 2007)
New Revision: 6835

Modified:
   trunk/conntrack-tools/extensions/libct_proto_udp.c
   trunk/conntrack-tools/include/cache.h
   trunk/conntrack-tools/include/conntrackd.h
   trunk/conntrack-tools/include/debug.h
   trunk/conntrack-tools/src/cache.c
   trunk/conntrack-tools/src/cache_iterators.c
   trunk/conntrack-tools/src/netlink.c
   trunk/conntrack-tools/src/run.c
   trunk/conntrack-tools/src/stats-mode.c
   trunk/conntrack-tools/src/sync-mode.c
Log:
- introduce cache_iterate
- empty debug_ct function if DEBUG_CT is not set
- revisit overrun handler: this is a hard battle, just try to do our best here, call Patrick :)
- explicit warning message when netlink_buffer_max_growth is reached
- fix silly bug in stats-mode when dumping in XML format
- fix UDP handler for conntrack



Modified: trunk/conntrack-tools/extensions/libct_proto_udp.c
===================================================================
--- trunk/conntrack-tools/extensions/libct_proto_udp.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/extensions/libct_proto_udp.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -43,12 +43,10 @@
 
 static int parse_options(char c, char *argv[],
 			 struct nf_conntrack *ct,
-			 struct nfct_tuple *exptuple,
-			 struct nfct_tuple *mask,
+			 struct nf_conntrack *exptuple,
+			 struct nf_conntrack *mask,
 			 unsigned int *flags)
 {
-	int i;
-
 	switch(c) {
 		case '1':
 			if (!optarg)
@@ -91,28 +89,44 @@
 			*flags |= UDP_REPL_DPORT;
 			break;
 		case '5':
-			if (optarg) {
-				mask->l4src.udp.port = htons(atoi(optarg));
-				*flags |= UDP_MASK_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(mask,
+					  ATTR_ORIG_PORT_SRC,
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_MASK_SPORT;
 			break;
 		case '6':
-			if (optarg) {
-				mask->l4dst.udp.port = htons(atoi(optarg));
-				*flags |= UDP_MASK_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(mask, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_MASK_DPORT;
 			break;
 		case '7':
-			if (optarg) {
-				exptuple->l4src.udp.port = htons(atoi(optarg));
-				*flags |= UDP_EXPTUPLE_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(exptuple, 
+					  ATTR_ORIG_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_EXPTUPLE_SPORT;
 			break;
 		case '8':
-			if (optarg) {
-				exptuple->l4dst.udp.port = htons(atoi(optarg));
-				*flags |= UDP_EXPTUPLE_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(exptuple, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_EXPTUPLE_DPORT;
 			break;
 	}
 	return 1;

Modified: trunk/conntrack-tools/include/cache.h
===================================================================
--- trunk/conntrack-tools/include/cache.h	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/include/cache.h	2007-05-20 21:13:06 UTC (rev 6835)
@@ -82,6 +82,7 @@
 void cache_stats(struct cache *c, int fd);
 struct us_conntrack *cache_get_conntrack(struct cache *, void *);
 void *cache_get_extra(struct cache *, void *);
+void cache_iterate(struct cache *c, void *data, int (*iterate)(void *data1, void *data2));
 
 /* iterators */
 void cache_dump(struct cache *c, int fd, int type);

Modified: trunk/conntrack-tools/include/conntrackd.h
===================================================================
--- trunk/conntrack-tools/include/conntrackd.h	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/include/conntrackd.h	2007-05-20 21:13:06 UTC (rev 6835)
@@ -102,11 +102,9 @@
 	struct ignore_pool		*ignore_pool;
 
 	struct nfnl_handle		*event;         /* event handler */
-	struct nfnl_handle		*sync;          /* sync handler */
 	struct nfnl_handle		*dump;		/* dump handler */
 
 	struct nfnl_subsys_handle	*subsys_event;  /* events */
-	struct nfnl_subsys_handle	*subsys_sync;	/* resync */
 	struct nfnl_subsys_handle	*subsys_dump;   /* dump */
 
 	/* statistics */
@@ -159,7 +157,7 @@
 	int (*local)(int fd, int type, void *data);
 	void (*kill)(void);
 	void (*dump)(struct nf_conntrack *ct, struct nlmsghdr *nlh);
-	void (*overrun)(struct nf_conntrack *ct, struct nlmsghdr *nlh);
+	void (*overrun)(void);
 	void (*event_new)(struct nf_conntrack *ct, struct nlmsghdr *nlh);
 	void (*event_upd)(struct nf_conntrack *ct, struct nlmsghdr *nlh);
 	int (*event_dst)(struct nf_conntrack *ct, struct nlmsghdr *nlh);

Modified: trunk/conntrack-tools/include/debug.h
===================================================================
--- trunk/conntrack-tools/include/debug.h	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/include/debug.h	2007-05-20 21:13:06 UTC (rev 6835)
@@ -11,8 +11,11 @@
 #include <netinet/in.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
 
+#undef DEBUG_CT
+
 static inline void debug_ct(struct nf_conntrack *ct, char *msg)
 {
+#ifdef DEBUG_CT
 	struct in_addr addr, addr2, addr3, addr4;
 
 	debug("----%s (%p) ----\n", msg, ct);
@@ -48,6 +51,7 @@
 			inet_ntoa(addr4),
 			ntohs(nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST)));
 	debug("-------------------------\n");
+#endif
 }
 
 #endif

Modified: trunk/conntrack-tools/src/cache.c
===================================================================
--- trunk/conntrack-tools/src/cache.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/cache.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -445,3 +445,12 @@
 	unlock();
 	send(fd, buf, size, 0);
 }
+
+void cache_iterate(struct cache *c, 
+		   void *data, 
+		   int (*iterate)(void *data1, void *data2))
+{
+	lock();
+	hashtable_iterate(c->h, data, iterate);
+	unlock();
+}

Modified: trunk/conntrack-tools/src/cache_iterators.c
===================================================================
--- trunk/conntrack-tools/src/cache_iterators.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/cache_iterators.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -111,7 +111,7 @@
 	 */
 	nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(commit_timeout));
 
-        ret = nfct_build_query(STATE(subsys_sync),
+        ret = nfct_build_query(STATE(subsys_dump),
 			       NFCT_Q_CREATE,
 			       ct,
 			       nlh,
@@ -125,7 +125,7 @@
 		return 0;
 	}
 
-	ret = nfnl_query(STATE(sync), nlh);
+	ret = nfnl_query(STATE(dump), nlh);
 	if (ret == -1) {
 		switch(errno) {
 			case EEXIST:
@@ -211,7 +211,7 @@
 	struct nlnetwork *net = (struct nlnetwork *) buf;
 
 	ret = build_network_msg(NFCT_Q_UPDATE,
-				STATE(subsys_sync),
+				STATE(subsys_dump),
 				u->ct,
 				buf,
 				sizeof(buf));

Modified: trunk/conntrack-tools/src/netlink.c
===================================================================
--- trunk/conntrack-tools/src/netlink.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/netlink.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -207,66 +207,6 @@
 	return 0;
 }
 
-static int nl_overrun_handler(struct nlmsghdr *nlh,
-			      struct nfattr *nfa[],
-			      void *data)
-{
-	char buf[1024];
-	struct nf_conntrack *ct = (struct nf_conntrack *) buf;
-	int type;
-
-	memset(buf, 0, sizeof(buf));
-
-	if ((type = nfct_parse_conntrack(NFCT_T_ALL, nlh, ct)) == NFCT_T_ERROR)
-		return NFCT_CB_CONTINUE;
-
-	/* 
-	 * Ignore this conntrack: it talks about a
-	 * connection that is not interesting for us.
-	 */
-	if (ignore_conntrack(ct))
-		return NFCT_CB_CONTINUE;
-
-	switch(type) {
-	case NFCT_T_UPDATE:
-		if (STATE(mode)->overrun)
-			STATE(mode)->overrun(ct, nlh);
-		break;
-	default:
-		dlog(STATE(log), "received unknown msg from ctnetlink");
-		break;
-	}
-	return NFCT_CB_CONTINUE;
-}
-
-int nl_init_overrun_handler(void)
-{
-	struct nfnl_callback cb_sync = {
-		.call		= nl_overrun_handler,
-		.attr_count	= CTA_MAX
-	};
-
-	/* open sync netlink socket */
-	STATE(sync) = nfnl_open();
-	if (!STATE(sync))
-		return -1;
-
-	/* open synchronizer subsystem */
-	STATE(subsys_sync) = nfnl_subsys_open(STATE(sync),
-					      NFNL_SUBSYS_CTNETLINK,
-					      IPCTNL_MSG_MAX,
-					      0);
-	if (STATE(subsys_sync) == NULL)
-		return -1;
-
-	/* register callback for dumped entries */
-	nfnl_callback_register(STATE(subsys_sync),
-			       IPCTNL_MSG_CT_NEW,
-			       &cb_sync);
-
-	return 0;
-}
-
 static int warned = 0;
 
 void nl_resize_socket_buffer(struct nfnl_handle *h)
@@ -278,7 +218,14 @@
 		return;
 
 	if (s > CONFIG(netlink_buffer_size_max_grown)) {
-		dlog(STATE(log), "maximum netlink socket buffer size reached");
+		dlog(STATE(log), "WARNING: maximum netlink socket buffer "
+				 "size has been reached. We are likely to "
+				 "be losing events, this may lead to "
+				 "unsynchronized replicas. Please, consider "
+				 "increasing netlink socket buffer size via "
+				 "SocketBufferSize and "
+				 "SocketBufferSizeMaxGrown clauses in "
+				 "conntrackd.conf");
 		s = CONFIG(netlink_buffer_size_max_grown);
 		warned = 1;
 	}
@@ -313,13 +260,13 @@
 	struct nfnlhdr req;
 
 	memset(&req, 0, sizeof(req));
-	nfct_build_query(STATE(subsys_sync), 
+	nfct_build_query(STATE(subsys_dump), 
 			 NFCT_Q_FLUSH, 
 			 &CONFIG(family), 
 			 &req, 
 			 sizeof(req));
 
-	if (nfnl_query(STATE(sync), &req.nlh) == -1)
+	if (nfnl_query(STATE(dump), &req.nlh) == -1)
 		return -1;
 
 	return 0;

Modified: trunk/conntrack-tools/src/run.c
===================================================================
--- trunk/conntrack-tools/src/run.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/run.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -32,10 +32,8 @@
 
 	nfnl_subsys_close(STATE(subsys_event));
 	nfnl_subsys_close(STATE(subsys_dump));
-	nfnl_subsys_close(STATE(subsys_sync));
 	nfnl_close(STATE(event));
 	nfnl_close(STATE(dump));
-	nfnl_close(STATE(sync));
 
 	ignore_pool_destroy(STATE(ignore_pool));
 	local_server_destroy(STATE(local));
@@ -120,12 +118,6 @@
 		return -1;
 	}
 
-	if (nl_init_overrun_handler() == -1) {
-		dlog(STATE(log), "[FAIL] can't open netlink handler! "
-				 "no ctnetlink kernel support?");
-		return -1;
-	}
-
         /* Signals handling */
 	sigemptyset(&STATE(block));
 	sigaddset(&STATE(block), SIGTERM);
@@ -196,8 +188,7 @@
 				 * size and resync with master conntrack table.
 				 */
 				nl_resize_socket_buffer(STATE(event));
-				nl_dump_conntrack_table(STATE(sync),
-							STATE(subsys_sync));
+				STATE(mode)->overrun();
 				break;
 			case ENOENT:
 				/*

Modified: trunk/conntrack-tools/src/stats-mode.c
===================================================================
--- trunk/conntrack-tools/src/stats-mode.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/stats-mode.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -1,5 +1,5 @@
 /*
- * (C) 2006 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * (C) 2006-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,7 +65,7 @@
 		cache_dump(STATE_STATS(cache), fd, NFCT_O_PLAIN);
 		break;
 	case DUMP_INT_XML:
-		cache_dump(STATE_SYNC(internal), fd, NFCT_O_XML);
+		cache_dump(STATE_STATS(cache), fd, NFCT_O_XML);
 		break;
 	case FLUSH_CACHE:
 		dlog(STATE(log), "[REQ] flushing caches");
@@ -92,6 +92,48 @@
 		debug_ct(ct, "resync entry");
 }
 
+static int overrun_cb(enum nf_conntrack_msg_type type,
+		      struct nf_conntrack *ct,
+		      void *data)
+{
+	/* This is required by kernels < 2.6.20 */
+	nfct_attr_unset(ct, ATTR_TIMEOUT);
+	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
+	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
+	nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES);
+	nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS);
+	nfct_attr_unset(ct, ATTR_USE);
+
+	if (!cache_test(STATE_STATS(cache), ct))
+		if (!cache_update_force(STATE_STATS(cache), ct))
+			debug_ct(ct, "overrun stats resync");
+
+	return NFCT_CB_CONTINUE;
+}
+
+static void overrun_stats()
+{
+	int ret;
+	struct nfct_handle *h;
+	int family = CONFIG(family);
+
+	h = nfct_open(CONNTRACK, 0);
+	if (!h) {
+		dlog(STATE(log), "can't open overrun handler");
+		return;
+	}
+
+	nfct_callback_register(h, NFCT_T_ALL, overrun_cb, NULL);
+
+	cache_flush(STATE_STATS(cache));
+
+	ret = nfct_query(h, NFCT_Q_DUMP, &family);
+	if (ret == -1)
+		dlog(STATE(log), "overrun query error %s", strerror(errno));
+
+	nfct_close(h);
+}
+
 static void event_new_stats(struct nf_conntrack *ct, struct nlmsghdr *nlh)
 {
 	debug_ct(ct, "debug event");
@@ -144,7 +186,7 @@
 	.local			= local_handler_stats,
 	.kill			= kill_stats,
 	.dump			= dump_stats,
-	.overrun		= dump_stats,
+	.overrun		= overrun_stats,
 	.event_new		= event_new_stats,
 	.event_upd		= event_update_stats,
 	.event_dst		= event_destroy_stats

Modified: trunk/conntrack-tools/src/sync-mode.c
===================================================================
--- trunk/conntrack-tools/src/sync-mode.c	2007-05-20 20:29:53 UTC (rev 6834)
+++ trunk/conntrack-tools/src/sync-mode.c	2007-05-20 21:13:06 UTC (rev 6835)
@@ -1,5 +1,5 @@
 /*
- * (C) 2006 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * (C) 2006-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -293,7 +293,9 @@
 	STATE_SYNC(mcast_sync)->post_send(type, net, u);
 }
 
-static void overrun_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh)
+static int overrun_cb(enum nf_conntrack_msg_type type,
+		      struct nf_conntrack *ct,
+		      void *data)
 {
 	struct us_conntrack *u;
 
@@ -307,12 +309,89 @@
 
 	if (!cache_test(STATE_SYNC(internal), ct)) {
 		if ((u = cache_update_force(STATE_SYNC(internal), ct))) {
-			debug_ct(ct, "overrun resync");
+			int ret;
+			char buf[4096];
+			struct nlnetwork *net = (struct nlnetwork *) buf;
+			unsigned int size = sizeof(struct nlnetwork);
+			struct nlmsghdr *nlh = (struct nlmsghdr *) (buf + size);
+
+			debug_ct(u->ct, "overrun resync");
+
+			ret = build_network_msg(NFCT_Q_UPDATE,
+						STATE(subsys_dump),
+						u->ct,
+						buf,
+						sizeof(buf));
+
+			if (ret == -1) {
+				dlog(STATE(log), "can't build overrun");
+				return NFCT_CB_CONTINUE;
+			}
+
 			mcast_send_sync(nlh, u, ct, NFCT_T_UPDATE);
 		}
 	}
+
+	return NFCT_CB_CONTINUE;
 }
 
+static int overrun_purge_step(void *data1, void *data2)
+{
+	int ret;
+	struct nfct_handle *h = data1;
+	struct us_conntrack *u = data2;
+
+	ret = nfct_query(h, NFCT_Q_GET, u->ct);
+	if (ret == -1 && errno == ENOENT) {
+		char buf[4096];
+		struct nlnetwork *net = (struct nlnetwork *) buf;
+		unsigned int size = sizeof(struct nlnetwork);
+		struct nlmsghdr *nlh = (struct nlmsghdr *) (buf + size);
+
+		debug_ct(u->ct, "overrun purge resync");
+
+		ret = build_network_msg(NFCT_Q_DESTROY,
+					STATE(subsys_dump),
+					u->ct,
+					buf,
+					sizeof(buf));
+
+		if (ret == -1)
+			dlog(STATE(log), "failed to build network message");
+
+		mcast_send_sync(nlh, NULL, u->ct, NFCT_T_DESTROY);
+		__cache_del(STATE_SYNC(internal), u->ct);
+	}
+
+	return 0;
+}
+
+/* it's likely that we're losing events, just try to do our best here */
+static void overrun_sync()
+{
+	int ret;
+	struct nfct_handle *h;
+	int family = CONFIG(family);
+
+	h = nfct_open(CONNTRACK, 0);
+	if (!h) {
+		dlog(STATE(log), "can't open overrun handler");
+		return;
+	}
+
+	nfct_callback_register(h, NFCT_T_ALL, overrun_cb, NULL);
+
+	ret = nfct_query(h, NFCT_Q_DUMP, &family);
+	if (ret == -1)
+		dlog(STATE(log), "overrun query error %s", strerror(errno));
+
+	nfct_callback_unregister(h);
+
+	cache_iterate(STATE_SYNC(internal), h, overrun_purge_step);
+
+	nfct_close(h);
+}
+
 static void event_new_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh)
 {
 	struct us_conntrack *u;




More information about the netfilter-cvslog mailing list