summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/sync/alarm/conntrackd.conf11
-rw-r--r--doc/sync/ftfw/conntrackd.conf11
-rw-r--r--doc/sync/keepalived.conf1
-rw-r--r--doc/sync/notrack/conntrackd.conf11
-rwxr-xr-xdoc/sync/primary-backup.sh12
-rw-r--r--include/conntrackd.h1
-rw-r--r--src/cache_iterators.c17
-rw-r--r--src/read_config_lex.l1
-rw-r--r--src/read_config_yy.y12
-rw-r--r--src/sync-mode.c15
10 files changed, 71 insertions, 21 deletions
diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf
index a65a378..d6f7a2a 100644
--- a/doc/sync/alarm/conntrackd.conf
+++ b/doc/sync/alarm/conntrackd.conf
@@ -23,6 +23,17 @@ Sync {
# takeover process is completed.
#
CommitTimeout 180
+
+ #
+ # If the firewall replica goes from primary to backup,
+ # the conntrackd -t command is invoked in the script.
+ # This command resets the timers of the conntracks that
+ # live in the kernel to this new value. This is useful
+ # to purge the connection tracking table of zombie entries
+ # and avoid clashes with old entries if you trigger
+ # several consecutive hand-overs.
+ #
+ PurgeTimeout 15
}
#
diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf
index 6fec9a1..8f4d952 100644
--- a/doc/sync/ftfw/conntrackd.conf
+++ b/doc/sync/ftfw/conntrackd.conf
@@ -16,6 +16,17 @@ Sync {
#
CommitTimeout 180
+ #
+ # If the firewall replica goes from primary to backup,
+ # the conntrackd -t command is invoked in the script.
+ # This command resets the timers of the conntracks that
+ # live in the kernel to this new value. This is useful
+ # to purge the connection tracking table of zombie entries
+ # and avoid clashes with old entries if you trigger
+ # several consecutive hand-overs.
+ #
+ PurgeTimeout 15
+
# Set Acknowledgement window size
ACKWindowSize 20
}
diff --git a/doc/sync/keepalived.conf b/doc/sync/keepalived.conf
index c9c8ac1..84f1383 100644
--- a/doc/sync/keepalived.conf
+++ b/doc/sync/keepalived.conf
@@ -9,6 +9,7 @@ vrrp_sync_group G1 { # must be before vrrp_instance declaration
}
notify_master "/etc/conntrackd/primary-backup.sh primary"
notify_backup "/etc/conntrackd/primary-backup.sh backup"
+ notify_fault "/etc/conntrackd/primary-backup.sh fault"
}
vrrp_instance VI_1 {
diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf
index d54934a..3ce1fa0 100644
--- a/doc/sync/notrack/conntrackd.conf
+++ b/doc/sync/notrack/conntrackd.conf
@@ -9,6 +9,17 @@ Sync {
# takeover process is completed.
#
CommitTimeout 180
+
+ #
+ # If the firewall replica goes from primary to backup,
+ # the conntrackd -t command is invoked in the script.
+ # This command resets the timers of the conntracks that
+ # live in the kernel to this new value. This is useful
+ # to purge the connection tracking table of zombie entries
+ # and avoid clashes with old entries if you trigger
+ # several consecutive hand-overs.
+ #
+ PurgeTimeout 15
}
#
diff --git a/doc/sync/primary-backup.sh b/doc/sync/primary-backup.sh
index 27fb1c3..e5331e3 100755
--- a/doc/sync/primary-backup.sh
+++ b/doc/sync/primary-backup.sh
@@ -95,9 +95,19 @@ case "$1" in
logger "ERROR: failed to invoke conntrackd -n"
fi
;;
+ fault)
+ #
+ # shorten kernel conntrack timers to remove the zombie entries.
+ #
+ $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -t
+ if [ $? -eq 1 ]
+ then
+ logger "ERROR: failed to invoke conntrackd -t"
+ fi
+ ;;
*)
logger "ERROR: unknown state transition"
- echo "Usage: primary-backup.sh {primary|backup}"
+ echo "Usage: primary-backup.sh {primary|backup|fault}"
exit 1
;;
esac
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 60bb2de..23f5306 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -79,6 +79,7 @@ struct ct_conf {
int refresh;
int cache_timeout; /* cache entries timeout */
int commit_timeout; /* committed entries timeout */
+ unsigned int purge_timeout; /* purge kernel entries timeout */
int del_timeout;
unsigned int netlink_buffer_size;
unsigned int netlink_buffer_size_max_grown;
diff --git a/src/cache_iterators.c b/src/cache_iterators.c
index a7c6654..8898930 100644
--- a/src/cache_iterators.c
+++ b/src/cache_iterators.c
@@ -55,6 +55,10 @@ static int do_dump(void *data1, void *data2)
if (CONFIG(flags) & CTD_SYNC_FTFW && alarm_pending(&u->alarm))
return 0;
+ /* do not show cached timeout, this may confuse users */
+ if (nfct_attr_is_set(u->ct, ATTR_TIMEOUT))
+ nfct_attr_unset(u->ct, ATTR_TIMEOUT);
+
memset(buf, 0, sizeof(buf));
size = nfct_snprintf(buf,
sizeof(buf),
@@ -177,13 +181,11 @@ void cache_commit(struct cache *c)
static int do_reset_timers(void *data1, void *data2)
{
int ret;
+ u_int32_t current_timeout;
struct us_conntrack *u = data2;
struct nf_conntrack *ct = u->ct;
- /* this may increase timers but they will end up dying shortly anyway */
- nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(commit_timeout));
-
- ret = nl_exist_conntrack(ct);
+ ret = nl_get_conntrack(ct);
switch (ret) {
case -1:
/* the kernel table is not in sync with internal cache */
@@ -191,6 +193,13 @@ static int do_reset_timers(void *data1, void *data2)
dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
break;
case 1:
+ current_timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
+ /* already about to die, do not touch it */
+ if (current_timeout < CONFIG(purge_timeout))
+ break;
+
+ nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(purge_timeout));
+
if (nl_update_conntrack(ct) == -1) {
if (errno == ETIME || errno == ENOENT)
break;
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index 584a4a3..79d5b89 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -111,6 +111,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k]
"State" { return T_STATE; }
"Accept" { return T_ACCEPT; }
"Ignore" { return T_IGNORE; }
+"PurgeTimeout" { return T_PURGE; }
{is_on} { return T_ON; }
{is_off} { return T_OFF; }
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index 33a435c..c7bce82 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -52,7 +52,7 @@ static void __kernel_filter_add_state(int value);
%token T_GENERAL T_SYNC T_STATS T_RELAX_TRANSITIONS T_BUFFER_SIZE T_DELAY
%token T_SYNC_MODE T_LISTEN_TO T_FAMILY T_RESEND_BUFFER_SIZE
%token T_ALARM T_FTFW T_CHECKSUM T_WINDOWSIZE T_ON T_OFF
-%token T_REPLICATE T_FOR T_IFACE
+%token T_REPLICATE T_FOR T_IFACE T_PURGE
%token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT
%token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN
%token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT
@@ -163,6 +163,11 @@ timeout: T_TIMEOUT T_NUMBER
conf.commit_timeout = $2;
};
+purge: T_PURGE T_NUMBER
+{
+ conf.purge_timeout = $2;
+};
+
checksum: T_CHECKSUM T_ON
{
conf.mcast.checksum = 0;
@@ -427,6 +432,7 @@ sync_list:
sync_line: refreshtime
| expiretime
| timeout
+ | purge
| checksum
| multicast_line
| relax_transitions
@@ -987,6 +993,10 @@ init_config(char *filename)
if (CONFIG(commit_timeout) == 0)
CONFIG(commit_timeout) = 180;
+ /* default to 15 seconds: purge kernel entries */
+ if (CONFIG(purge_timeout) == 0)
+ CONFIG(purge_timeout) = 15;
+
/* default to 60 seconds of refresh time */
if (CONFIG(refresh) == 0)
CONFIG(refresh) = 60;
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 297a500..db199bc 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -378,9 +378,6 @@ static int local_handler_sync(int fd, int type, void *data)
static void dump_sync(struct nf_conntrack *ct)
{
- if (!CONFIG(cache_write_through))
- nfct_attr_unset(ct, ATTR_TIMEOUT);
-
/* This is required by kernels < 2.6.20 */
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
@@ -438,9 +435,6 @@ static int overrun_sync(enum nf_conntrack_msg_type type,
if (ignore_conntrack(ct))
return NFCT_CB_CONTINUE;
- if (!CONFIG(cache_write_through))
- nfct_attr_unset(ct, ATTR_TIMEOUT);
-
/* This is required by kernels < 2.6.20 */
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
@@ -462,9 +456,6 @@ static void event_new_sync(struct nf_conntrack *ct)
{
struct us_conntrack *u;
- if (!CONFIG(cache_write_through))
- nfct_attr_unset(ct, ATTR_TIMEOUT);
-
/* required by linux kernel <= 2.6.20 */
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES);
nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS);
@@ -490,9 +481,6 @@ static void event_update_sync(struct nf_conntrack *ct)
{
struct us_conntrack *u;
- if (!CONFIG(cache_write_through))
- nfct_attr_unset(ct, ATTR_TIMEOUT);
-
if ((u = cache_update_force(STATE_SYNC(internal), ct)) == NULL) {
debug_ct(ct, "can't update");
return;
@@ -505,9 +493,6 @@ static int event_destroy_sync(struct nf_conntrack *ct)
{
struct us_conntrack *u;
- if (!CONFIG(cache_write_through))
- nfct_attr_unset(ct, ATTR_TIMEOUT);
-
u = cache_find(STATE_SYNC(internal), ct);
if (u == NULL) {
debug_ct(ct, "can't destroy");