diff options
-rw-r--r-- | doc/sync/alarm/conntrackd.conf | 11 | ||||
-rw-r--r-- | doc/sync/ftfw/conntrackd.conf | 11 | ||||
-rw-r--r-- | doc/sync/keepalived.conf | 1 | ||||
-rw-r--r-- | doc/sync/notrack/conntrackd.conf | 11 | ||||
-rwxr-xr-x | doc/sync/primary-backup.sh | 12 | ||||
-rw-r--r-- | include/conntrackd.h | 1 | ||||
-rw-r--r-- | src/cache_iterators.c | 17 | ||||
-rw-r--r-- | src/read_config_lex.l | 1 | ||||
-rw-r--r-- | src/read_config_yy.y | 12 | ||||
-rw-r--r-- | src/sync-mode.c | 15 |
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"); |