diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-05-23 20:34:41 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-05-23 20:34:41 +0200 |
commit | 6f5666a29cb7cbff08ce926ee1edb84a311ff6ee (patch) | |
tree | 650dc13ca2677bdd1d661d10cd4f0453ca475f26 /src/sync-mode.c | |
parent | ef047d03613bf9fa105db009773136817e2ec4c6 (diff) | |
download | conntrack-tools-6f5666a29cb7cbff08ce926ee1edb84a311ff6ee.tar.gz conntrack-tools-6f5666a29cb7cbff08ce926ee1edb84a311ff6ee.zip |
conntrackd: flush operation use the child process and origin infrastructure
With this patch, the flush operation is performed by a child process.
Thus, the parent process digests destroy events that ctnetlink reports
back and, thanks to the origin infrastructure, we skip the messy
implicit synchronization that are triggered by such events.
This patch requires a Linux kernel >= 2.6.29 to benefit from this
change, otherwise it has no effect.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/sync-mode.c')
-rw-r--r-- | src/sync-mode.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/sync-mode.c b/src/sync-mode.c index 91e028e..a0ba830 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -203,11 +203,37 @@ static void interface_handler(void) interface_candidate(); } +/* this is called once the flusher process has finished */ +static void flush_done_cb(void *data) +{ + struct nfct_handle *h = data; + origin_unregister(h); + nfct_close(h); +} + static void do_reset_cache_alarm(struct alarm_block *a, void *data) { + struct nfct_handle *h; + + /* disposable flusher handler */ + h = nfct_open(CONNTRACK, 0); + if (h == NULL) { + dlog(LOG_ERR, "cannot open flusher handler"); + return; + } + /* register this handler as the origin of a flush operation */ + origin_register(h, CTD_ORIGIN_FLUSH); + STATE(stats).nl_kernel_table_flush++; dlog(LOG_NOTICE, "flushing kernel conntrack table (scheduled)"); - nl_flush_conntrack_table(STATE(request)); + + /* fork a child process that performs the flush operation, + * meanwhile the parent process handles events. */ + if (fork_process_new(flush_done_cb, h) == 0) { + nl_flush_conntrack_table(h); + exit(EXIT_SUCCESS); + } + /* this is not required if events don't get lost */ cache_flush(STATE_SYNC(internal)); } |