summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-rw-r--r--src/cache_iterators.c34
-rw-r--r--src/main.c4
-rw-r--r--src/sync-mode.c8
3 files changed, 46 insertions, 0 deletions
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));