diff options
-rw-r--r-- | include/netlink.h | 2 | ||||
-rw-r--r-- | src/internal_bypass.c | 2 | ||||
-rw-r--r-- | src/netlink.c | 37 | ||||
-rw-r--r-- | src/run.c | 2 | ||||
-rw-r--r-- | src/sync-mode.c | 2 |
5 files changed, 39 insertions, 6 deletions
diff --git a/include/netlink.h b/include/netlink.h index 3bde30c..9a33083 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -12,7 +12,7 @@ struct nlif_handle *nl_init_interface_handler(void); int nl_send_resync(struct nfct_handle *h); void nl_resize_socket_buffer(struct nfct_handle *h); int nl_dump_conntrack_table(struct nfct_handle *h); -int nl_flush_conntrack_table(struct nfct_handle *h); +int nl_flush_conntrack_table_selective(void); int nl_get_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct); int nl_create_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct, int timeout); int nl_update_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct, int timeout); 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) @@ -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 */ |