On Fri, Oct 28, 2011 at 11:25 AM, Mike Belopuhov <m...@crypt.org.ru> wrote: > On Thu, Oct 27, 2011 at 11:18 AM, Mike Belopuhov <m...@crypt.org.ru> wrote: >>>> On 26-10-2011 20:32, Maxim Bourmistrov wrote: >>>>> The side question, after observing 'systat -s1 states', is WHY "failover"-side >>>>> doubles exp. time?? >>>>> I'm more expected to have it like a "copy" of the current state of the >>>>> master. >> >> i've started looking into the problem, but it's not yet apparent as to >> why it happens. >> > > ok, so what i've figured out is that expire timeouts are transferred > as values of "rule->timeout[state->timeout]" and not absolute ones > (to compensate for a local time difference). but when you insert > the rule into the state table you have to subtract the timeout value > as pf_state_expires does a good job itself by adding those back. > > so here's a diff. i've tried to solve "no adaptive scaling" caveat as well. > > ok? >
need to assign a rule pointer before dereferencing it, right? Index: if_pfsync.c =================================================================== RCS file: /cvs/src/sys/net/if_pfsync.c,v retrieving revision 1.169 diff -u -p -u -p -r1.169 if_pfsync.c --- if_pfsync.c 20 Oct 2011 08:57:26 -0000 1.169 +++ if_pfsync.c 28 Oct 2011 13:46:12 -0000 @@ -266,6 +266,8 @@ void pfsync_bulk_status(u_int8_t); void pfsync_bulk_update(void *); void pfsync_bulk_fail(void *); +u_int32_t pfsync_expires(const struct pf_state *, u_int32_t, u_int8_t); + #define PFSYNC_MAX_BULKTRIES 12 int pfsync_sync_ok; @@ -578,13 +580,7 @@ pfsync_state_import(struct pfsync_state /* copy to state */ bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); st->creation = time_second - ntohl(sp->creation); - st->expire = time_second; - if (sp->expire) { - /* XXX No adaptive scaling. */ - st->expire -= r->timeout[sp->timeout] - ntohl(sp->expire); - } - st->expire = ntohl(sp->expire) + time_second; st->direction = sp->direction; st->log = sp->log; st->timeout = sp->timeout; @@ -603,6 +599,8 @@ pfsync_state_import(struct pfsync_state st->anchor.ptr = NULL; st->rt_kif = NULL; + st->expire = pfsync_expires(st, ntohl(sp->expire), sp->timeout); + st->pfsync_time = time_uptime; st->sync_state = PFSYNC_S_NONE; @@ -948,7 +946,8 @@ pfsync_in_upd(caddr_t buf, int len, int if (sync < 2) { pfsync_alloc_scrub_memory(&sp->dst, &st->dst); pf_state_peer_ntoh(&sp->dst, &st->dst); - st->expire = ntohl(sp->expire) + time_second; + st->expire = pfsync_expires(st, ntohl(sp->expire), + sp->timeout); st->timeout = sp->timeout; } st->pfsync_time = time_uptime; @@ -1019,10 +1018,12 @@ pfsync_in_upd_c(caddr_t buf, int len, in else pf_state_peer_ntoh(&up->dst, &st->dst); } + if (sync < 2) { pfsync_alloc_scrub_memory(&up->dst, &st->dst); pf_state_peer_ntoh(&up->dst, &st->dst); - st->expire = ntohl(up->expire) + time_second; + st->expire = pfsync_expires(st, ntohl(up->expire), + up->timeout); st->timeout = up->timeout; } st->pfsync_time = time_uptime; @@ -2330,4 +2331,37 @@ pfsync_sysctl(int *name, u_int namelen, default: return (ENOPROTOOPT); } +} + +u_int32_t +pfsync_expires(const struct pf_state *st, u_int32_t expire, u_int8_t ttype) +{ + u_int32_t start; + u_int32_t end; + u_int32_t states; + u_int32_t result; + u_int32_t timeout; + + if (expire == 0 || ttype >= PFTM_MAX) + return (time_second); + + timeout = st->rule.ptr->timeout[ttype]; + result = time_second - timeout + expire; + start = st->rule.ptr->timeout[PFTM_ADAPTIVE_START]; + if (start) { + end = st->rule.ptr->timeout[PFTM_ADAPTIVE_END]; + states = st->rule.ptr->states_cur; + } else { + start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; + end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; + states = pf_status.states; + } + if (end && states > start && start < end) { + if (states < end) + return (result + timeout * (end - states) / + (end - start)); + else + return (time_second); + } + return (result); }