summaryrefslogtreecommitdiff
path: root/src/run.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 20:34:41 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 20:34:41 +0200
commit6f5666a29cb7cbff08ce926ee1edb84a311ff6ee (patch)
tree650dc13ca2677bdd1d661d10cd4f0453ca475f26 /src/run.c
parentef047d03613bf9fa105db009773136817e2ec4c6 (diff)
downloadconntrack-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/run.c')
-rw-r--r--src/run.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/run.c b/src/run.c
index e54764c..990b202 100644
--- a/src/run.c
+++ b/src/run.c
@@ -181,6 +181,13 @@ static void dump_stats_runtime(int fd)
send(fd, buf, size, 0);
}
+static void flush_done_cb(void *data)
+{
+ struct nfct_handle *h = data;
+ origin_unregister(h);
+ nfct_close(h);
+}
+
void local_handler(int fd, void *data)
{
int ret;
@@ -195,11 +202,29 @@ void local_handler(int fd, void *data)
return;
switch(type) {
- case FLUSH_MASTER:
+ case FLUSH_MASTER: {
+ 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");
- 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);
+ }
return;
+ }
case RESYNC_MASTER:
STATE(stats).nl_kernel_table_resync++;
dlog(LOG_NOTICE, "resync with master table");