summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-08-02 18:59:36 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-08-02 18:59:36 +0200
commit16010f777b090b293a00072d8368e94418cc99f8 (patch)
tree42e7f36cb86952ae21fb670a18c6660c1ba16627
parentc403246424350bae14a30fc6a115608ca15f2aa1 (diff)
conntrackd: add -t option to shorten conntrack timeouts
This patch adds the new option `-t' for conntrackd. This option shortens the value of the timeout for the cached entries that lives in the kernel. This option is particularly useful to remove the zombie established entries that remain in kernel if the user tests the platform by forcing the takeover from one to another node several times. We currently use the value of CommitTimeout which is sane for it. Adding a new option does not seem to add more flexibility IMO. Once we get the patches to notify user changes via ctnetlink and the netlink flag NLM_F_ECHO works, we may directly invoke a massive purge of the entries, however, such solution would still need evaluation. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/cache.h1
-rw-r--r--include/conntrackd.h1
-rw-r--r--src/cache_iterators.c34
-rw-r--r--src/main.c4
-rw-r--r--src/sync-mode.c8
5 files changed, 48 insertions, 0 deletions
diff --git a/include/cache.h b/include/cache.h
index ba8d3aa..45c3b7e 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -97,5 +97,6 @@ void cache_dump(struct cache *c, int fd, int type);
void cache_commit(struct cache *c);
void cache_flush(struct cache *c);
void cache_bulk(struct cache *c);
+void cache_reset_timers(struct cache *c);
#endif
diff --git a/include/conntrackd.h b/include/conntrackd.h
index d2c8931..2f0d7e5 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -24,6 +24,7 @@
#define REQUEST_DUMP 23 /* request dump */
#define DUMP_INT_XML 24 /* dump internal cache in XML */
#define DUMP_EXT_XML 25 /* dump external cache in XML */
+#define RESET_TIMERS 26 /* reset kernel timers */
#define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf"
#define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock"
diff --git a/src/cache_iterators.c b/src/cache_iterators.c
index 407db0b..2abb6cd 100644
--- a/src/cache_iterators.c
+++ b/src/cache_iterators.c
@@ -174,6 +174,40 @@ void cache_commit(struct cache *c)
"committed", commit_fail);
}
+static int do_reset_timers(void *data1, void *data2)
+{
+ int ret;
+ struct us_conntrack *u = data2;
+ struct nf_conntrack *ct = u->ct;
+
+ /* this may increase timers but they will end up dying shortly anyway */
+ nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(commit_timeout));
+
+ ret = nl_exist_conntrack(ct);
+ switch (ret) {
+ case -1:
+ case 0:
+ /* the kernel table is not in sync with internal cache */
+ dlog(LOG_ERR, "reset-timers: %s", strerror(errno));
+ dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+ break;
+ case 1:
+ if (nl_update_conntrack(ct) == -1) {
+ if (errno == ETIME || errno == ENOENT)
+ break;
+ dlog(LOG_ERR, "reset-timers-upd: %s", strerror(errno));
+ dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
+ }
+ break;
+ }
+ return 0;
+}
+
+void cache_reset_timers(struct cache *c)
+{
+ hashtable_iterate(c->h, NULL, do_reset_timers);
+}
+
static int do_flush(void *data1, void *data2)
{
struct cache *c = data1;
diff --git a/src/main.c b/src/main.c
index 084643c..a4c5451 100644
--- a/src/main.c
+++ b/src/main.c
@@ -148,6 +148,10 @@ int main(int argc, char *argv[])
set_operation_mode(&type, REQUEST, argv);
action = SEND_BULK;
break;
+ case 't':
+ set_operation_mode(&type, REQUEST, argv);
+ action = RESET_TIMERS;
+ break;
case 'k':
set_operation_mode(&type, REQUEST, argv);
action = KILL;
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 56c30af..297a500 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -343,6 +343,14 @@ static int local_handler_sync(int fd, int type, void *data)
exit(EXIT_SUCCESS);
}
break;
+ case RESET_TIMERS:
+ ret = fork();
+ if (ret == 0) {
+ dlog(LOG_NOTICE, "resetting timers");
+ cache_reset_timers(STATE_SYNC(internal));
+ exit(EXIT_SUCCESS);
+ }
+ break;
case FLUSH_CACHE:
dlog(LOG_NOTICE, "flushing caches");
cache_flush(STATE_SYNC(internal));