[conntrack-tools] netlink: add new option NetlinkOverrunResync

Pablo Neira netfilter-cvslog-bounces at lists.netfilter.org
Sun Feb 8 19:13:43 CET 2009


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=conntrack-tools.git;a=commit;h=f3464ea99081fbe4f429f030ea99c60e2338c047
commit f3464ea99081fbe4f429f030ea99c60e2338c047
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Sun Feb 8 19:13:22 2009 +0100
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Sun Feb 8 19:13:22 2009 +0100

    netlink: add new option NetlinkOverrunResync
    
    This patch adds NetlinkOverrunResync. This option can be used to
    set the amount of time after which the daemon resynchronizes itself
    with the kernel state-table if it detects a Netlink overrun.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

commit ba2f8458ecfa0827e09a1c40c9e29868239fafa1
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Fri Feb 6 17:43:40 2009 +0100
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Fri Feb 6 17:43:40 2009 +0100

    src: re-work polling strategy
    
    This patch improves the polling support included in 0.9.10. The
    polling now consists of getting the state table, wait for PollSecs,
    then purge obsolete entries, and so on.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
       via  f3464ea99081fbe4f429f030ea99c60e2338c047 (commit)
       via  ba2f8458ecfa0827e09a1c40c9e29868239fafa1 (commit)
      from  c3ef4d9b32ca653571f0976f73aaa99218a36db0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f3464ea99081fbe4f429f030ea99c60e2338c047
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Sun Feb 8 19:13:22 2009 +0100

    netlink: add new option NetlinkOverrunResync
    
    This patch adds NetlinkOverrunResync. This option can be used to
    set the amount of time after which the daemon resynchronizes itself
    with the kernel state-table if it detects a Netlink overrun.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

commit ba2f8458ecfa0827e09a1c40c9e29868239fafa1
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Fri Feb 6 17:43:40 2009 +0100

    src: re-work polling strategy
    
    This patch improves the polling support included in 0.9.10. The
    polling now consists of getting the state table, wait for PollSecs,
    then purge obsolete entries, and so on.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

-----------------------------------------------------------------------

 doc/sync/alarm/conntrackd.conf   |   13 +++++
 doc/sync/ftfw/conntrackd.conf    |   13 +++++
 doc/sync/notrack/conntrackd.conf |   13 +++++
 include/conntrackd.h             |    5 ++
 src/read_config_lex.l            |    1 +
 src/read_config_yy.y             |   23 +++++++++-
 src/run.c                        |   93 +++++++++++++++++++++++++------------
 src/stats-mode.c                 |    6 +-
 src/sync-mode.c                  |   28 +++++++-----
 9 files changed, 150 insertions(+), 45 deletions(-)
This patch improves the polling support included in 0.9.10. The
polling now consists of getting the state table, wait for PollSecs,
then purge obsolete entries, and so on.

Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

diff --git a/include/conntrackd.h b/include/conntrackd.h
index 3e10a2f..34c7629 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -114,7 +114,11 @@ struct ct_general_state {
 	struct nfct_handle		*dump;		/* dump handler */
 	struct nfct_handle		*request;	/* request handler */
 	struct nfct_handle		*resync;	/* resync handler */
+	struct nfct_handle		*get;		/* get handler */
+	int				get_retval;	/* hackish */
+
 	struct alarm_block		resync_alarm;
+	struct alarm_block		polling_alarm;
 
 	struct fds			*fds;
 
diff --git a/src/run.c b/src/run.c
index 7d48865..81f2590 100644
--- a/src/run.c
+++ b/src/run.c
@@ -1,5 +1,5 @@
 /*
- * (C) 2006-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * (C) 2006-2009 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
@@ -40,8 +40,11 @@ void killer(int foo)
 	/* no signals while handling signals */
 	sigprocmask(SIG_BLOCK, &STATE(block), NULL);
 
-	if (!(CONFIG(flags) & CTD_POLL))
+	if (!(CONFIG(flags) & CTD_POLL)) {
 		nfct_close(STATE(event));
+		nfct_close(STATE(resync));
+	}
+	nfct_close(STATE(get));
 	nfct_close(STATE(request));
 
 	if (STATE(us_filter))
@@ -212,10 +215,13 @@ static void do_overrun_resync_alarm(struct alarm_block *a, void *data)
 	STATE(stats).nl_kernel_table_resync++;
 }
 
-static void do_poll_resync_alarm(struct alarm_block *a, void *data)
+static void do_polling_alarm(struct alarm_block *a, void *data)
 {
-	nl_send_resync(STATE(resync));
-	add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+	if (STATE(mode)->purge)
+		STATE(mode)->purge();
+
+	nl_send_resync(STATE(dump));
+	add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0);
 }
 
 static int event_handler(enum nf_conntrack_msg_type type,
@@ -272,6 +278,17 @@ static int dump_handler(enum nf_conntrack_msg_type type,
 	return NFCT_CB_CONTINUE;
 }
 
+static int get_handler(enum nf_conntrack_msg_type type,
+		       struct nf_conntrack *ct,
+		       void *data)
+{
+	if (ct_filter_conntrack(ct, 1))
+		return NFCT_CB_CONTINUE;
+
+	STATE(get_retval) = 1;
+	return NFCT_CB_CONTINUE;
+}
+
 int
 init(void)
 {
@@ -316,6 +333,20 @@ init(void)
 		nfct_callback_register(STATE(event), NFCT_T_ALL,
 				       event_handler, NULL);
 		register_fd(nfct_fd(STATE(event)), STATE(fds));
+
+		STATE(resync) = nfct_open(CONNTRACK, 0);
+		if (STATE(resync)== NULL) {
+			dlog(LOG_ERR, "can't open netlink handler: %s",
+			     strerror(errno));
+			dlog(LOG_ERR, "no ctnetlink kernel support?");
+			return -1;
+		}
+		nfct_callback_register(STATE(resync),
+				       NFCT_T_ALL,
+				       STATE(mode)->resync,
+				       NULL);
+		register_fd(nfct_fd(STATE(resync)), STATE(fds));
+		fcntl(nfct_fd(STATE(resync)), F_SETFL, O_NONBLOCK);
 	}
 
 	STATE(dump) = nfct_open(CONNTRACK, 0);
@@ -326,25 +357,22 @@ init(void)
 		return -1;
 	}
 	nfct_callback_register(STATE(dump), NFCT_T_ALL, dump_handler, NULL);
+	if (CONFIG(flags) & CTD_POLL)
+		register_fd(nfct_fd(STATE(dump)), STATE(fds));
 
 	if (nl_dump_conntrack_table(STATE(dump)) == -1) {
 		dlog(LOG_ERR, "can't get kernel conntrack table");
 		return -1;
 	}
 
-	STATE(resync) = nfct_open(CONNTRACK, 0);
-	if (STATE(resync)== NULL) {
+	STATE(get) = nfct_open(CONNTRACK, 0);
+	if (STATE(get) == NULL) {
 		dlog(LOG_ERR, "can't open netlink handler: %s",
 		     strerror(errno));
 		dlog(LOG_ERR, "no ctnetlink kernel support?");
 		return -1;
 	}
-	nfct_callback_register(STATE(resync),
-			       NFCT_T_ALL,
-			       STATE(mode)->resync,
-			       NULL);
-	register_fd(nfct_fd(STATE(resync)), STATE(fds));
-	fcntl(nfct_fd(STATE(resync)), F_SETFL, O_NONBLOCK);
+	nfct_callback_register(STATE(get), NFCT_T_ALL, get_handler, NULL);
 
 	/* no callback, it does not do anything with the output */
 	STATE(request) = nfct_open(CONNTRACK, 0);
@@ -356,8 +384,8 @@ init(void)
 	}
 
 	if (CONFIG(flags) & CTD_POLL) {
-		init_alarm(&STATE(resync_alarm), NULL, do_poll_resync_alarm);
-		add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+		init_alarm(&STATE(polling_alarm), NULL, do_polling_alarm);
+		add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0);
 		dlog(LOG_NOTICE, "running in polling mode");
 	} else {
 		init_alarm(&STATE(resync_alarm), NULL, do_overrun_resync_alarm);
@@ -414,11 +442,11 @@ static void __run(struct timeval *next_alarm)
 	if (FD_ISSET(STATE(local).fd, &readfds))
 		do_local_server_step(&STATE(local), NULL, local_handler);
 
-	/* conntrack event has happened */
-	if (!(CONFIG(flags) & CTD_POLL) &&
-	    FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
-		ret = nfct_catch(STATE(event));
-		if (ret == -1) {
+	if (!(CONFIG(flags) & CTD_POLL)) {
+		/* conntrack event has happened */
+		if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
+			ret = nfct_catch(STATE(event));
+			if (ret == -1) {
 			switch(errno) {
 			case ENOBUFS:
 				/* We have hit ENOBUFS, it's likely that we are
@@ -464,13 +492,18 @@ static void __run(struct timeval *next_alarm)
 				STATE(stats).nl_catch_event_failed++;
 				break;
 			}
+			}
+		}
+		if (FD_ISSET(nfct_fd(STATE(resync)), &readfds)) {
+			nfct_catch(STATE(resync));
+			if (STATE(mode)->purge)
+				STATE(mode)->purge();
+		}
+	} else {
+		/* using polling mode */
+		if (FD_ISSET(nfct_fd(STATE(dump)), &readfds)) {
+			nfct_catch(STATE(dump));
 		}
-	}
-
-	if (FD_ISSET(nfct_fd(STATE(resync)), &readfds)) {
-		nfct_catch(STATE(resync));
-		if (STATE(mode)->purge)
-			STATE(mode)->purge();
 	}
 
 	if (STATE(mode)->run)
diff --git a/src/stats-mode.c b/src/stats-mode.c
index 226a6b8..bd20253 100644
--- a/src/stats-mode.c
+++ b/src/stats-mode.c
@@ -123,11 +123,11 @@ static int resync_stats(enum nf_conntrack_msg_type type,
 
 static int purge_step(void *data1, void *data2)
 {
-	int ret;
 	struct cache_object *obj = data2;
 
-	ret = nfct_query(STATE(dump), NFCT_Q_GET, obj->ct);
-	if (ret == -1 && errno == ENOENT) {
+	STATE(get_retval) = 0;
+	nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_retval) */
+	if (!STATE(get_retval)) {
 		debug_ct(obj->ct, "purge stats");
 		cache_del(STATE_STATS(cache), obj);
 		cache_object_free(obj);
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 84a4de0..8174681 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -499,8 +499,15 @@ static int local_handler_sync(int fd, int type, void *data)
 	return ret;
 }
 
+static void mcast_send_sync(struct cache_object *obj, int query)
+{
+	STATE_SYNC(sync)->enqueue(obj, query);
+}
+
 static void dump_sync(struct nf_conntrack *ct)
 {
+	struct cache_object *obj;
+
 	/* This is required by kernels < 2.6.20 */
 	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
 	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
@@ -508,23 +515,22 @@ static void dump_sync(struct nf_conntrack *ct)
 	nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS);
 	nfct_attr_unset(ct, ATTR_USE);
 
-	if (cache_update_force(STATE_SYNC(internal), ct))
-		debug_ct(ct, "resync");
-}
-
-static void mcast_send_sync(struct cache_object *obj, int query)
-{
-	STATE_SYNC(sync)->enqueue(obj, query);
+	obj = cache_update_force(STATE_SYNC(internal), ct);
+	if ((CONFIG(flags) & CTD_POLL)) {
+		if (obj != NULL && obj->status == C_OBJ_NEW) {
+			debug_ct(ct, "poll");
+			mcast_send_sync(obj, NET_T_STATE_NEW);
+		}
+	}
 }
 
 static int purge_step(void *data1, void *data2)
 {
-	int ret;
-	struct nfct_handle *h = STATE(dump);
 	struct cache_object *obj = data2;
 
-	ret = nfct_query(h, NFCT_Q_GET, obj->ct);
-	if (ret == -1 && errno == ENOENT) {
+	STATE(get_retval) = 0;
+	nl_get_conntrack(STATE(get), obj->ct);	/* modifies STATE(get_reval) */
+	if (!STATE(get_retval)) {
 		debug_ct(obj->ct, "purge resync");
 		if (obj->status != C_OBJ_DEAD) {
 			cache_object_set_status(obj, C_OBJ_DEAD);



More information about the netfilter-cvslog mailing list