summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/netlink.h2
-rw-r--r--src/internal_bypass.c2
-rw-r--r--src/netlink.c37
-rw-r--r--src/run.c2
-rw-r--r--src/sync-mode.c2
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)
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 */