[netfilter-cvslog] r7456 - in trunk/conntrack-tools: . include src

pablo at netfilter.org pablo at netfilter.org
Wed Apr 9 17:26:00 CEST 2008


Author: pablo at netfilter.org
Date: 2008-04-09 17:25:59 +0200 (Wed, 09 Apr 2008)
New Revision: 7456

Modified:
   trunk/conntrack-tools/ChangeLog
   trunk/conntrack-tools/include/conntrackd.h
   trunk/conntrack-tools/include/netlink.h
   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:
improve netlink overrun handling


Modified: trunk/conntrack-tools/ChangeLog
===================================================================
--- trunk/conntrack-tools/ChangeLog	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/ChangeLog	2008-04-09 15:25:59 UTC (rev 7456)
@@ -5,6 +5,7 @@
 o remove .svn directory from make distcheck tarballs (reported by B.Benjamini)
 o fix minor compilation issue in amd64 with gcc4.3 (reported by Daniel Schepler)
 o fix asymmetric path support (reported by Gary Richards)
+o improve netlink overrun handling
 
 Krzysztof Oledzki <ole at ans.pl>:
 o fix minor compilation warning

Modified: trunk/conntrack-tools/include/conntrackd.h
===================================================================
--- trunk/conntrack-tools/include/conntrackd.h	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/include/conntrackd.h	2008-04-09 15:25:59 UTC (rev 7456)
@@ -3,6 +3,7 @@
 
 #include "mcast.h"
 #include "local.h"
+#include "alarm.h"
 
 #include <stdint.h>
 #include <stdio.h>
@@ -104,6 +105,8 @@
 
 	struct nfct_handle		*event;         /* event handler */
 	struct nfct_handle		*dump;		/* dump handler */
+	struct nfct_handle		*overrun;	/* overrun handler */
+	struct alarm_block		overrun_alarm;
 
 	struct fds			*fds;
 
@@ -158,7 +161,10 @@
 	int (*local)(int fd, int type, void *data);
 	void (*kill)(void);
 	void (*dump)(struct nf_conntrack *ct);
-	void (*overrun)(void);
+	int (*overrun)(enum nf_conntrack_msg_type type,
+		       struct nf_conntrack *ct,
+		       void *data);
+	int (*purge)(void);
 	void (*event_new)(struct nf_conntrack *ct);
 	void (*event_upd)(struct nf_conntrack *ct);
 	int (*event_dst)(struct nf_conntrack *ct);

Modified: trunk/conntrack-tools/include/netlink.h
===================================================================
--- trunk/conntrack-tools/include/netlink.h	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/include/netlink.h	2008-04-09 15:25:59 UTC (rev 7456)
@@ -10,6 +10,10 @@
 
 int nl_init_dump_handler(void);
 
+int nl_init_overrun_handler(void);
+
+int nl_overrun_request_resync(void);
+
 void nl_resize_socket_buffer(struct nfct_handle *h);
 
 int nl_dump_conntrack_table(void);

Modified: trunk/conntrack-tools/src/netlink.c
===================================================================
--- trunk/conntrack-tools/src/netlink.c	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/src/netlink.c	2008-04-09 15:25:59 UTC (rev 7456)
@@ -158,6 +158,21 @@
 	return 0;
 }
 
+int nl_init_overrun_handler(void)
+{
+	STATE(overrun) = nfct_open(CONNTRACK, 0);
+	if (!STATE(overrun))
+		return -1;
+
+	fcntl(nfct_fd(STATE(overrun)), F_SETFL, O_NONBLOCK);
+
+	nfct_callback_register(STATE(overrun), 
+			       NFCT_T_ALL, 
+			       STATE(mode)->overrun, 
+			       NULL);
+	return 0;
+}
+
 static int warned = 0;
 
 void nl_resize_socket_buffer(struct nfct_handle *h)
@@ -195,6 +210,12 @@
 	return nfct_query(STATE(dump), NFCT_Q_DUMP, &CONFIG(family));
 }
 
+int nl_overrun_request_resync(void)
+{
+	int family = CONFIG(family);
+	return nfct_send(STATE(overrun), NFCT_Q_DUMP, &family);
+}
+
 int nl_exist_conntrack(struct nf_conntrack *ct)
 {
 	int ret;

Modified: trunk/conntrack-tools/src/run.c
===================================================================
--- trunk/conntrack-tools/src/run.c	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/src/run.c	2008-04-09 15:25:59 UTC (rev 7456)
@@ -89,6 +89,12 @@
 		dlog(LOG_WARNING, "unknown local request %d", type);
 }
 
+static void do_overrun_alarm(struct alarm_block *a, void *data)
+{
+	nl_overrun_request_resync();
+	add_alarm(&STATE(overrun_alarm), 2, 0);
+}
+
 int
 init(void)
 {
@@ -129,6 +135,15 @@
 		return -1;
 	}
 
+	if (nl_init_overrun_handler() == -1) {
+		dlog(LOG_ERR, "can't open netlink handler: %s",
+		     strerror(errno));
+		dlog(LOG_ERR, "no ctnetlink kernel support?");
+		return -1;
+	}
+
+	init_alarm(&STATE(overrun_alarm), NULL, do_overrun_alarm);
+
 	STATE(fds) = create_fds();
 	if (STATE(fds) == NULL) {
 		dlog(LOG_ERR, "can't create file descriptor pool");
@@ -137,6 +152,7 @@
 
 	register_fd(STATE(local).fd, STATE(fds));
 	register_fd(nfct_fd(STATE(event)), STATE(fds));
+	register_fd(nfct_fd(STATE(overrun)), STATE(fds));
 
 	if (STATE(mode)->register_fds &&
 	    STATE(mode)->register_fds(STATE(fds)) == -1) {
@@ -203,8 +219,8 @@
 				 * size and resync with master conntrack table.
 				 */
 				nl_resize_socket_buffer(STATE(event));
-				/* XXX: schedule overrun call via alarm */
-				STATE(mode)->overrun();
+				nl_overrun_request_resync();
+				add_alarm(&STATE(overrun_alarm), 2, 0);
 				break;
 			case ENOENT:
 				/*
@@ -223,6 +239,13 @@
 		}
 	}
 
+	if (FD_ISSET(nfct_fd(STATE(overrun)), &readfds)) {
+		del_alarm(&STATE(overrun_alarm));
+		nfct_catch(STATE(overrun));
+		if (STATE(mode)->purge)
+			STATE(mode)->purge();
+	}
+
 	if (STATE(mode)->run)
 		STATE(mode)->run(&readfds);
 

Modified: trunk/conntrack-tools/src/stats-mode.c
===================================================================
--- trunk/conntrack-tools/src/stats-mode.c	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/src/stats-mode.c	2008-04-09 15:25:59 UTC (rev 7456)
@@ -22,10 +22,12 @@
 #include "cache.h"
 #include "log.h"
 #include "conntrackd.h"
+#include "us-conntrack.h"
 
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
 
 static int init_stats(void)
 {
@@ -93,9 +95,9 @@
 		debug_ct(ct, "resync entry");
 }
 
-static int overrun_cb(enum nf_conntrack_msg_type type,
-		      struct nf_conntrack *ct,
-		      void *data)
+static int overrun_stats(enum nf_conntrack_msg_type type,
+			 struct nf_conntrack *ct,
+			 void *data)
 {
 	if (ignore_conntrack(ct))
 		return NFCT_CB_CONTINUE;
@@ -115,28 +117,25 @@
 	return NFCT_CB_CONTINUE;
 }
 
-static void overrun_stats(void)
+static int purge_step(void *data1, void *data2)
 {
 	int ret;
-	struct nfct_handle *h;
-	int family = CONFIG(family);
+	struct us_conntrack *u = data2;
 
-	h = nfct_open(CONNTRACK, 0);
-	if (!h) {
-		dlog(LOG_ERR, "can't open overrun handler");
-		return;
+	ret = nfct_query(STATE(dump), NFCT_Q_GET, u->ct);
+	if (ret == -1 && errno == ENOENT) {
+		debug_ct(u->ct, "overrun purge stats");
+		cache_del(STATE_STATS(cache), u->ct);
 	}
 
-	nfct_callback_register(h, NFCT_T_ALL, overrun_cb, NULL);
+	return 0;
+}
 
-	cache_flush(STATE_STATS(cache));
+static int purge_stats(void)
+{
+	cache_iterate(STATE_STATS(cache), NULL, purge_step);
 
-	ret = nfct_query(h, NFCT_Q_DUMP, &family);
-	if (ret == -1)
-		dlog(LOG_ERR, 
-		     "overrun query error %s", strerror(errno));
-
-	nfct_close(h);
+	return 0;
 }
 
 static void event_new_stats(struct nf_conntrack *ct)
@@ -187,6 +186,7 @@
 	.kill			= kill_stats,
 	.dump			= dump_stats,
 	.overrun		= overrun_stats,
+	.purge			= purge_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	2008-04-09 13:58:36 UTC (rev 7455)
+++ trunk/conntrack-tools/src/sync-mode.c	2008-04-09 15:25:59 UTC (rev 7456)
@@ -350,10 +350,41 @@
 		STATE_SYNC(sync)->send(net, u);
 }
 
-static int overrun_cb(enum nf_conntrack_msg_type type,
-		      struct nf_conntrack *ct,
-		      void *data)
+static int purge_step(void *data1, void *data2)
 {
+	int ret;
+	struct nfct_handle *h = STATE(dump);
+	struct us_conntrack *u = data2;
+
+	ret = nfct_query(h, NFCT_Q_GET, u->ct);
+	if (ret == -1 && errno == ENOENT) {
+		size_t len;
+		struct nethdr *net = BUILD_NETMSG(u->ct, NFCT_Q_DESTROY);
+
+		debug_ct(u->ct, "overrun purge resync");
+
+	        len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
+	        mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len);
+		if (STATE_SYNC(sync)->send)
+			STATE_SYNC(sync)->send(net, u);
+
+		cache_del(STATE_SYNC(internal), u->ct);
+	}
+
+	return 0;
+}
+
+static int purge_sync(void)
+{
+	cache_iterate(STATE_SYNC(internal), NULL, purge_step);
+
+	return 0;
+}
+
+static int overrun_sync(enum nf_conntrack_msg_type type,
+			struct nf_conntrack *ct,
+			void *data)
+{
 	struct us_conntrack *u;
 
 	if (ignore_conntrack(ct))
@@ -387,57 +418,6 @@
 	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) {
-		size_t len;
-		struct nethdr *net = BUILD_NETMSG(u->ct, NFCT_Q_DESTROY);
-
-		debug_ct(u->ct, "overrun purge resync");
-
-	        len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
-	        mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len);
-		if (STATE_SYNC(sync)->send)
-			STATE_SYNC(sync)->send(net, u);
-
-		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(void)
-{
-	int ret;
-	struct nfct_handle *h;
-	int family = CONFIG(family);
-
-	h = nfct_open(CONNTRACK, 0);
-	if (!h) {
-		dlog(LOG_ERR, "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(LOG_ERR, 
-		     "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 us_conntrack *u;
@@ -505,6 +485,7 @@
 	.kill			= kill_sync,
 	.dump			= dump_sync,
 	.overrun		= overrun_sync,
+	.purge			= purge_sync,
 	.event_new		= event_new_sync,
 	.event_upd		= event_update_sync,
 	.event_dst		= event_destroy_sync




More information about the netfilter-cvslog mailing list