[conntrack-tools] conntrackd: add `DisableExternalCache' clause

Pablo Neira netfilter-cvslog-bounces at lists.netfilter.org
Wed Aug 19 17:00:09 CEST 2009


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=conntrack-tools.git;a=commit;h=3e6852f806c4368eda451b39f12b2ac2f2b5d33b
commit 3e6852f806c4368eda451b39f12b2ac2f2b5d33b
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Wed Aug 19 16:59:38 2009 +0200
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Wed Aug 19 16:59:38 2009 +0200

    conntrackd: add `DisableExternalCache' clause
    
    This patch adds the clause `DisableExternalCache' that allows you
    to disable the external cache and to directly inject the entries
    into the kernel conntrack table. As a result, the CPU consumption
    of conntrackd increases. This clause can only be used with the
    FT-FW and the notrack synchronization modes, but not with the
    alarm mode.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
       via  3e6852f806c4368eda451b39f12b2ac2f2b5d33b (commit)
      from  32ca6a144903b2e6318ee61d1dda3f670d3c09da (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 3e6852f806c4368eda451b39f12b2ac2f2b5d33b
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Wed Aug 19 16:59:38 2009 +0200

    conntrackd: add `DisableExternalCache' clause
    
    This patch adds the clause `DisableExternalCache' that allows you
    to disable the external cache and to directly inject the entries
    into the kernel conntrack table. As a result, the CPU consumption
    of conntrackd increases. This clause can only be used with the
    FT-FW and the notrack synchronization modes, but not with the
    alarm mode.
    
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

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

 doc/sync/ftfw/conntrackd.conf    |   13 +++
 doc/sync/notrack/conntrackd.conf |   13 +++
 include/Makefile.am              |    2 +-
 include/conntrackd.h             |    5 +-
 include/external.h               |   24 ++++++
 include/origin.h                 |    1 +
 src/Makefile.am                  |    1 +
 src/external_cache.c             |  122 +++++++++++++++++++++++++++++++
 src/external_inject.c            |  150 ++++++++++++++++++++++++++++++++++++++
 src/read_config_lex.l            |    1 +
 src/read_config_yy.y             |   13 +++
 src/sync-mode.c                  |   73 ++++++++----------
 12 files changed, 375 insertions(+), 43 deletions(-)
 create mode 100644 include/external.h
 create mode 100644 src/external_cache.c
 create mode 100644 src/external_inject.c
This patch adds the clause `DisableExternalCache' that allows you
to disable the external cache and to directly inject the entries
into the kernel conntrack table. As a result, the CPU consumption
of conntrackd increases. This clause can only be used with the
FT-FW and the notrack synchronization modes, but not with the
alarm mode.

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

diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf
index 602c3d1..76c3aef 100644
--- a/doc/sync/ftfw/conntrackd.conf
+++ b/doc/sync/ftfw/conntrackd.conf
@@ -189,6 +189,19 @@ Sync {
 		#
 		# Checksum on
 	# }
+
+	#
+	# This clause allows you to disable the external cache. Thus, the
+	# state entries are directly injected into the kernel conntrack
+	# table. As a result, you save memory in user-space but you consume
+	# slots in the kernel conntrack table for backup state entries.
+	# Moreover, disabling the external cache means more CPU consumption.
+	# You need a Linux kernel >= 2.6.29 to use this feature. By default,
+	# this clause is set off. If you are installing conntrackd for first
+	# time, please read the user manual and I encourage you to consider
+	# using the fail-over scripts instead of enabling this option!
+	#
+	# DisableExternalCache Off
 }
 
 #
diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf
index 6968025..9cdb2c7 100644
--- a/doc/sync/notrack/conntrackd.conf
+++ b/doc/sync/notrack/conntrackd.conf
@@ -170,6 +170,19 @@ Sync {
 		#
 		# Checksum on
 	# }
+
+	#
+	# This clause allows you to disable the external cache. Thus, the
+	# state entries are directly injected into the kernel conntrack
+	# table. As a result, you save memory in user-space but you consume
+	# slots in the kernel conntrack table for backup state entries.
+	# Moreover, disabling the external cache means more CPU consumption.
+	# You need a Linux kernel >= 2.6.29 to use this feature. By default,
+	# this clause is set off. If you are installing conntrackd for first
+	# time, please read the user manual and I encourage you to consider
+	# using the fail-over scripts instead of enabling this option!
+	#
+	# DisableExternalCache Off
 }
 
 #
diff --git a/include/Makefile.am b/include/Makefile.am
index b72fb36..0fa76af 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -4,5 +4,5 @@ noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \
 		 debug.h log.h hash.h mcast.h conntrack.h \
 		 network.h filter.h queue.h vector.h cidr.h \
 		 traffic_stats.h netlink.h fds.h event.h bitops.h channel.h \
-		 process.h origin.h
+		 process.h origin.h external.h
 
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 907ce33..ce8f9d4 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -96,6 +96,9 @@ struct ct_conf {
 	int filter_from_kernelspace;
 	int event_iterations_limit;
 	struct {
+		int external_cache_disable;
+	} sync;
+	struct {
 		int events_reliable;
 	} netlink;
 	struct {
@@ -172,7 +175,7 @@ struct ct_general_state {
 
 struct ct_sync_state {
 	struct cache *internal; 	/* internal events cache (netlink) */
-	struct cache *external; 	/* external events cache (mcast) */
+	struct external_handler *external;
 
 	struct multichannel	*channel;
 	struct nlif_handle	*interface;
diff --git a/include/external.h b/include/external.h
new file mode 100644
index 0000000..938941a
--- /dev/null
+++ b/include/external.h
@@ -0,0 +1,24 @@
+#ifndef _EXTERNAL_H_
+#define _EXTERNAL_H_
+
+struct nf_conntrack;
+
+struct external_handler {
+	int	(*init)(void);
+	void	(*close)(void);
+
+	void	(*new)(struct nf_conntrack *ct);
+	void	(*update)(struct nf_conntrack *ct);
+	void	(*destroy)(struct nf_conntrack *ct);
+
+	void	(*dump)(int fd, int type);
+	void	(*flush)(void);
+	void	(*commit)(struct nfct_handle *h, int fd);
+	void	(*stats)(int fd);
+	void	(*stats_ext)(int fd);
+};
+
+extern struct external_handler external_cache;
+extern struct external_handler external_inject;
+
+#endif
diff --git a/include/origin.h b/include/origin.h
index 89308f3..1b974e9 100644
--- a/include/origin.h
+++ b/include/origin.h
@@ -6,6 +6,7 @@ enum {
 					   any process, but not conntrackd */
 	CTD_ORIGIN_COMMIT,		/* event comes from committer */
 	CTD_ORIGIN_FLUSH,		/* event comes from flush */
+	CTD_ORIGIN_INJECT,		/* event comes from direct inject */
 };
 
 int origin_register(struct nfct_handle *h, int origin_type);
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c8b34f..753c809 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \
 		    network.c cidr.c \
 		    build.c parse.c \
 		    channel.c multichannel.c channel_mcast.c channel_udp.c \
+		    external_cache.c external_inject.c \
 		    read_config_yy.y read_config_lex.l
 
 # yacc and lex generate dirty code
diff --git a/src/external_cache.c b/src/external_cache.c
new file mode 100644
index 0000000..c70c818
--- /dev/null
+++ b/src/external_cache.c
@@ -0,0 +1,122 @@
+/*
+ * (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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "conntrackd.h"
+#include "sync.h"
+#include "log.h"
+#include "cache.h"
+#include "external.h"
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <stdlib.h>
+
+static struct cache *external;
+
+static int external_cache_init(void)
+{
+	external = cache_create("external",
+				STATE_SYNC(sync)->external_cache_flags,
+				NULL);
+	if (external == NULL) {
+		dlog(LOG_ERR, "can't allocate memory for the external cache");
+		return -1;
+	}
+	return 0;
+}
+
+static void external_cache_close(void)
+{
+	cache_destroy(external);
+}
+
+static void external_cache_new(struct nf_conntrack *ct)
+{
+	struct cache_object *obj;
+	int id;
+
+	obj = cache_find(external, ct, &id);
+	if (obj == NULL) {
+retry:
+		obj = cache_object_new(external, ct);
+		if (obj == NULL)
+			return;
+
+		if (cache_add(external, obj, id) == -1) {
+			cache_object_free(obj);
+			return;
+		}
+	} else {
+		cache_del(external, obj);
+		cache_object_free(obj);
+		goto retry;
+	}
+}
+
+static void external_cache_upd(struct nf_conntrack *ct)
+{
+	cache_update_force(external, ct);
+}
+
+static void external_cache_del(struct nf_conntrack *ct)
+{
+	struct cache_object *obj;
+	int id;
+
+	obj = cache_find(external, ct, &id);
+	if (obj) {
+		cache_del(external, obj);
+		cache_object_free(obj);
+	}
+}
+
+static void external_cache_dump(int fd, int type)
+{
+	cache_dump(external, fd, type);
+}
+
+static void external_cache_commit(struct nfct_handle *h, int fd)
+{
+	cache_commit(external, h, fd);
+}
+
+static void external_cache_flush(void)
+{
+	cache_flush(external);
+}
+
+static void external_cache_stats(int fd)
+{
+	cache_stats(external, fd);
+}
+
+static void external_cache_stats_ext(int fd)
+{
+	cache_stats_extended(external, fd);
+}
+
+struct external_handler external_cache = {
+	.init		= external_cache_init,
+	.close		= external_cache_close,
+	.new		= external_cache_new,
+	.update		= external_cache_upd,
+	.destroy	= external_cache_del,
+	.dump		= external_cache_dump,
+	.commit		= external_cache_commit,
+	.flush		= external_cache_flush,
+	.stats		= external_cache_stats,
+	.stats_ext	= external_cache_stats_ext,
+};
diff --git a/src/external_inject.c b/src/external_inject.c
new file mode 100644
index 0000000..ec1cb16
--- /dev/null
+++ b/src/external_inject.c
@@ -0,0 +1,150 @@
+/*
+ * (C) 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "conntrackd.h"
+#include "sync.h"
+#include "log.h"
+#include "cache.h"
+#include "origin.h"
+#include "external.h"
+#include "netlink.h"
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <errno.h>
+#include <stdlib.h>
+
+static struct nfct_handle *inject;
+
+static int external_inject_init(void)
+{
+	/* handler to directly inject conntracks into kernel-space */
+	inject = nfct_open(CONNTRACK, 0);
+	if (inject == NULL) {
+		dlog(LOG_ERR, "can't open netlink handler: %s",
+		     strerror(errno));
+		dlog(LOG_ERR, "no ctnetlink kernel support?");
+		return -1;
+	}
+	/* we are directly injecting the entries into the kernel */
+	origin_register(inject, CTD_ORIGIN_INJECT);
+	return 0;
+}
+
+static void external_inject_close(void)
+{
+	origin_unregister(inject);
+	nfct_close(inject);
+}
+
+static void external_inject_new(struct nf_conntrack *ct)
+{
+	int ret, retry = 1;
+
+retry:
+	if (nl_create_conntrack(inject, ct, 0) == -1) {
+		/* if the state entry exists, we delete and try again */
+		if (errno == EEXIST && retry == 1) {
+			ret = nl_destroy_conntrack(inject, ct);
+			if (ret == 0 || (ret == -1 && errno == ENOENT)) {
+				if (retry) {
+					retry = 0;
+					goto retry;
+				}
+			}
+			dlog(LOG_ERR, "inject-add1: %s", strerror(errno));
+			dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+			return;
+		}
+		dlog(LOG_ERR, "inject-add2: %s", strerror(errno));
+		dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+	}
+}
+
+static void external_inject_upd(struct nf_conntrack *ct)
+{
+	int ret;
+
+	/* if we successfully update the entry, everything is OK */
+	if (nl_update_conntrack(inject, ct, 0) != -1)
+		return;
+
+	/* state entries does not exist, we have to create it */
+	if (errno == ENOENT) {
+		if (nl_create_conntrack(inject, ct, 0) == -1) {
+			dlog(LOG_ERR, "inject-upd1: %s", strerror(errno));
+			dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+		}
+		return;
+	}
+
+	/* we failed to update the entry, there are some operations that
+	 * may trigger this error, eg. unset some status bits. Try harder,
+	 * delete the existing entry and create a new one. */
+	ret = nl_destroy_conntrack(inject, ct);
+	if (ret == 0 || (ret == -1 && errno == ENOENT)) {
+		if (nl_create_conntrack(inject, ct, 0) == -1) {
+			dlog(LOG_ERR, "inject-upd2: %s", strerror(errno));
+			dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+		}
+		return;
+	}
+	dlog(LOG_ERR, "inject-upd3: %s", strerror(errno));
+	dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+}
+
+static void external_inject_del(struct nf_conntrack *ct)
+{
+	if (nl_destroy_conntrack(inject, ct) == -1) {
+		if (errno != ENOENT) {
+			dlog(LOG_ERR, "inject-del: %s", strerror(errno));
+			dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+		}
+	}
+}
+
+static void external_inject_dump(int fd, int type)
+{
+}
+
+static void external_inject_commit(struct nfct_handle *h, int fd)
+{
+}
+
+static void external_inject_flush(void)
+{
+}
+
+static void external_inject_stats(int fd)
+{
+}
+
+static void external_inject_stats_ext(int fd)
+{
+}
+
+struct external_handler external_inject = {
+	.init		= external_inject_init,
+	.close		= external_inject_close,
+	.new		= external_inject_new,
+	.update		= external_inject_upd,
+	.destroy	= external_inject_del,
+	.dump		= external_inject_dump,
+	.commit		= external_inject_commit,
+	.flush		= external_inject_flush,
+	.stats		= external_inject_stats,
+	.stats_ext	= external_inject_stats_ext,
+};
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index dad7555..d3f83aa 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -135,6 +135,7 @@ notrack		[N|n][O|o][T|t][R|r][A|a][C|c][K|k]
 "Type"				{ return T_TYPE; }
 "Priority"			{ return T_PRIO; }
 "NetlinkEventsReliable"		{ return T_NETLINK_EVENTS_RELIABLE; }
+"DisableExternalCache"		{ return T_DISABLE_EXTERNAL_CACHE; }
 
 {is_on}			{ return T_ON; }
 {is_off}		{ return T_OFF; }
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index f3f4730..38c5929 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -72,6 +72,7 @@ static void __max_dedicated_links_reached(void);
 %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT
 %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR
 %token T_SCHEDULER T_TYPE T_PRIO T_NETLINK_EVENTS_RELIABLE
+%token T_DISABLE_EXTERNAL_CACHE
 
 %token <string> T_IP T_PATH_VAL
 %token <val> T_NUMBER
@@ -698,6 +699,7 @@ sync_mode_ftfw_line: resend_queue_size
 		   | timeout
 		   | purge
 		   | window_size
+		   | disable_external_cache
 		   ;
 
 sync_mode_notrack_list:
@@ -705,8 +707,19 @@ sync_mode_notrack_list:
 
 sync_mode_notrack_line: timeout
 		      | purge
+		      | disable_external_cache
 		      ;
 
+disable_external_cache: T_DISABLE_EXTERNAL_CACHE T_ON
+{
+	conf.sync.external_cache_disable = 1;
+};
+
+disable_external_cache: T_DISABLE_EXTERNAL_CACHE T_OFF
+{
+	conf.sync.external_cache_disable = 0;
+};
+
 resend_buffer_size: T_RESEND_BUFFER_SIZE T_NUMBER
 {
 	print_err(CTD_CFG_WARN, "`ResendBufferSize' is deprecated. "
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 9e3ac39..174df80 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -28,6 +28,7 @@
 #include "queue.h"
 #include "process.h"
 #include "origin.h"
+#include "external.h"
 
 #include <errno.h>
 #include <unistd.h>
@@ -43,8 +44,6 @@ do_channel_handler_step(int i, struct nethdr *net, size_t remain)
 {
 	char __ct[nfct_maxsize()];
 	struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct;
-	struct cache_object *obj;
-	int id;
 
 	if (net->version != CONNTRACKD_PROTOCOL_VERSION) {
 		STATE_SYNC(error).msg_rcv_malformed++;
@@ -84,32 +83,13 @@ do_channel_handler_step(int i, struct nethdr *net, size_t remain)
 
 	switch(net->type) {
 	case NET_T_STATE_NEW:
-		obj = cache_find(STATE_SYNC(external), ct, &id);
-		if (obj == NULL) {
-retry:
-			obj = cache_object_new(STATE_SYNC(external), ct);
-			if (obj == NULL)
-				return;
-
-			if (cache_add(STATE_SYNC(external), obj, id) == -1) {
-				cache_object_free(obj);
-				return;
-			}
-		} else {
-			cache_del(STATE_SYNC(external), obj);
-			cache_object_free(obj);
-			goto retry;
-		}
+		STATE_SYNC(external)->new(ct);
 		break;
 	case NET_T_STATE_UPD:
-		cache_update_force(STATE_SYNC(external), ct);
+		STATE_SYNC(external)->update(ct);
 		break;
 	case NET_T_STATE_DEL:
-		obj = cache_find(STATE_SYNC(external), ct, &id);
-		if (obj) {
-			cache_del(STATE_SYNC(external), obj);
-			cache_object_free(obj);
-		}
+		STATE_SYNC(external)->destroy(ct);
 		break;
 	default:
 		STATE_SYNC(error).msg_rcv_malformed++;
@@ -275,15 +255,14 @@ static int init_sync(void)
 		return -1;
 	}
 
-	STATE_SYNC(external) = 
-		cache_create("external",
-			     STATE_SYNC(sync)->external_cache_flags,
-			     NULL);
-
-	if (!STATE_SYNC(external)) {
-		dlog(LOG_ERR, "can't allocate memory for the external cache");
-		return -1;
+	if (CONFIG(sync).external_cache_disable == 0) {
+		STATE_SYNC(external) = &external_cache;
+	} else {
+		STATE_SYNC(external) = &external_inject;
+		dlog(LOG_NOTICE, "disabling external cache");
 	}
+	if (STATE_SYNC(external)->init() == -1)
+		return -1;
 
 	channel_init();
 
@@ -361,7 +340,7 @@ static void run_sync(fd_set *readfds)
 
 	if (FD_ISSET(get_read_evfd(STATE_SYNC(commit).evfd), readfds)) {
 		read_evfd(STATE_SYNC(commit).evfd);
-		cache_commit(STATE_SYNC(external), STATE_SYNC(commit).h, 0);
+		STATE_SYNC(external)->commit(STATE_SYNC(commit).h, 0);
 	}
 
 	/* flush pending messages */
@@ -371,7 +350,7 @@ static void run_sync(fd_set *readfds)
 static void kill_sync(void)
 {
 	cache_destroy(STATE_SYNC(internal));
-	cache_destroy(STATE_SYNC(external));
+	STATE_SYNC(external)->close();
 
 	multichannel_close(STATE_SYNC(channel));
 
@@ -452,7 +431,7 @@ static int local_handler_sync(int fd, int type, void *data)
 	case DUMP_EXTERNAL:
 		ret = fork_process_new(CTD_PROC_ANY, 0, NULL, NULL);
 		if (ret == 0) {
-			cache_dump(STATE_SYNC(external), fd, NFCT_O_PLAIN);
+			STATE_SYNC(external)->dump(fd, NFCT_O_PLAIN);
 			exit(EXIT_SUCCESS);
 		} 
 		break;
@@ -466,7 +445,7 @@ static int local_handler_sync(int fd, int type, void *data)
 	case DUMP_EXT_XML:
 		ret = fork_process_new(CTD_PROC_ANY, 0, NULL, NULL);
 		if (ret == 0) {
-			cache_dump(STATE_SYNC(external), fd, NFCT_O_XML);
+			STATE_SYNC(external)->dump(fd, NFCT_O_XML);
 			exit(EXIT_SUCCESS);
 		}
 		break;
@@ -475,7 +454,7 @@ static int local_handler_sync(int fd, int type, void *data)
 		del_alarm(&STATE_SYNC(reset_cache_alarm));
 
 		dlog(LOG_NOTICE, "committing external cache");
-		cache_commit(STATE_SYNC(external), STATE_SYNC(commit).h, fd);
+		STATE_SYNC(external)->commit(STATE_SYNC(commit).h, fd);
 		/* Keep the client socket open, we want synchronous commits. */
 		ret = LOCAL_RET_STOLEN;
 		break;
@@ -492,7 +471,7 @@ static int local_handler_sync(int fd, int type, void *data)
 		del_alarm(&STATE_SYNC(reset_cache_alarm));
 		dlog(LOG_NOTICE, "flushing caches");
 		cache_flush(STATE_SYNC(internal));
-		cache_flush(STATE_SYNC(external));
+		STATE_SYNC(external)->flush();
 		break;
 	case FLUSH_INT_CACHE:
 		/* inmediate flush, remove pending flush scheduled if any */
@@ -502,14 +481,14 @@ static int local_handler_sync(int fd, int type, void *data)
 		break;
 	case FLUSH_EXT_CACHE:
 		dlog(LOG_NOTICE, "flushing external cache");
-		cache_flush(STATE_SYNC(external));
+		STATE_SYNC(external)->flush();
 		break;
 	case KILL:
 		killer(0);
 		break;
 	case STATS:
 		cache_stats(STATE_SYNC(internal), fd);
-		cache_stats(STATE_SYNC(external), fd);
+		STATE_SYNC(external)->stats(fd);
 		dump_traffic_stats(fd);
 		multichannel_stats(STATE_SYNC(channel), fd);
 		dump_stats_sync(fd);
@@ -520,7 +499,7 @@ static int local_handler_sync(int fd, int type, void *data)
 		break;
 	case STATS_CACHE:
 		cache_stats_extended(STATE_SYNC(internal), fd);
-		cache_stats_extended(STATE_SYNC(external), fd);
+		STATE_SYNC(external)->stats_ext(fd);
 		break;
 	case STATS_LINK:
 		multichannel_stats_extended(STATE_SYNC(channel),
@@ -616,6 +595,10 @@ event_new_sync(struct nf_conntrack *ct, int origin)
 	struct cache_object *obj;
 	int id;
 
+	/* this event has been triggered by a direct inject, skip */
+	if (origin == CTD_ORIGIN_INJECT)
+		return;
+
 	/* required by linux kernel <= 2.6.20 */
 	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
 	nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
@@ -649,6 +632,10 @@ event_update_sync(struct nf_conntrack *ct, int origin)
 {
 	struct cache_object *obj;
 
+	/* this event has been triggered by a direct inject, skip */
+	if (origin == CTD_ORIGIN_INJECT)
+		return;
+
 	obj = cache_update_force(STATE_SYNC(internal), ct);
 	if (obj == NULL)
 		return;
@@ -663,6 +650,10 @@ event_destroy_sync(struct nf_conntrack *ct, int origin)
 	struct cache_object *obj;
 	int id;
 
+	/* this event has been triggered by a direct inject, skip */
+	if (origin == CTD_ORIGIN_INJECT)
+		return 0;
+
 	/* we don't synchronize events for objects that are not in the cache */
 	obj = cache_find(STATE_SYNC(internal), ct, &id);
 	if (obj == NULL)



More information about the netfilter-cvslog mailing list