From 3cd88a6d9c66360dad983578259ab92ba083fca8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 30 Jul 2012 02:22:58 +0200 Subject: conntrackd: implement selective flushing for `-t' and `-F' commands This patch changes the current behaviour of `-t' and `-F' commands, that results in flushing the kernel conntrack table. With this patch, the entries that match the Filter clauses in conntrackd.conf are ignored. This fixes the situation in which some local ssh connection to the firewall is lost during the failover (since `-t' is invoked from the primary-backup.sh script). Note that the Filter clause tells what entries have to be ignored, ie. the entries that do not need to be replicated. It makes sense not to flush entries that are not replicated (usually traffic to the local firewall). Reported-by: Gaurav Sinha Signed-off-by: Pablo Neira Ayuso --- src/internal_bypass.c | 2 +- src/netlink.c | 37 +++++++++++++++++++++++++++++++++++-- src/run.c | 2 +- src/sync-mode.c | 2 +- 4 files changed, 38 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/internal_bypass.c b/src/internal_bypass.c index 5c83c21..1194339 100644 --- a/src/internal_bypass.c +++ b/src/internal_bypass.c @@ -67,7 +67,7 @@ static void internal_bypass_ct_dump(int fd, int type) static void internal_bypass_ct_flush(void) { - nl_flush_conntrack_table(STATE(flush)); + nl_flush_conntrack_table_selective(); } struct { diff --git a/src/netlink.c b/src/netlink.c index fe979e3..bd38d99 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -151,9 +151,42 @@ int nl_dump_conntrack_table(struct nfct_handle *h) return nfct_query(h, NFCT_Q_DUMP, &CONFIG(family)); } -int nl_flush_conntrack_table(struct nfct_handle *h) +static int +nl_flush_selective_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) { - return nfct_query(h, NFCT_Q_FLUSH, &CONFIG(family)); + /* don't delete this conntrack, it's in the ignore filter */ + if (ct_filter_conntrack(ct, 1)) + return NFCT_CB_CONTINUE; + + switch(type) { + case NFCT_T_UPDATE: + nl_destroy_conntrack(STATE(flush), ct); + break; + default: + STATE(stats).nl_dump_unknown_type++; + break; + } + return NFCT_CB_CONTINUE; +} + +int nl_flush_conntrack_table_selective(void) +{ + struct nfct_handle *h; + int ret; + + h = nfct_open(CONNTRACK, 0); + if (h == NULL) { + dlog(LOG_ERR, "cannot open handle"); + return -1; + } + nfct_callback_register(h, NFCT_T_ALL, nl_flush_selective_cb, NULL); + + ret = nfct_query(h, NFCT_Q_DUMP, &CONFIG(family)); + + nfct_close(h); + + return ret; } int nl_send_resync(struct nfct_handle *h) diff --git a/src/run.c b/src/run.c index 26c1783..421ff41 100644 --- a/src/run.c +++ b/src/run.c @@ -196,7 +196,7 @@ static void local_flush_master(void) * meanwhile the parent process handles events. */ if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL, NULL, NULL) == 0) { - nl_flush_conntrack_table(STATE(flush)); + nl_flush_conntrack_table_selective(); exit(EXIT_SUCCESS); } } diff --git a/src/sync-mode.c b/src/sync-mode.c index 7fb3eba..17f866a 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -304,7 +304,7 @@ static void do_reset_cache_alarm(struct alarm_block *a, void *data) * meanwhile the parent process handles events. */ if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL, NULL, NULL) == 0) { - nl_flush_conntrack_table(STATE(flush)); + nl_flush_conntrack_table_selective(); exit(EXIT_SUCCESS); } /* this is not required if events don't get lost */ -- cgit v1.2.3