summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-08-07 14:53:12 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-08-07 14:53:12 +0200
commit6cb33c62c8007593d8a85aa202fa173043877135 (patch)
treec3fbcdbffb912d1abcff20846773f0663195c5ab
parenta4f4647b4b7f32f2d1caab98544802c8cdd7b4d6 (diff)
cache iterators: rework cache_reset_timers
This patch adds the clause PurgeTimeout that sets the new timer when conntrackd -t is called. This command is particularly useful when the sysadmin triggers hand-overs between several nodes without rebooting as it reduces the timers of the remaining entries in the kernel. Thus, avoiding clashes between new and old entries that may trigger INVALID packets. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-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");