On Thu, Oct 27, 2011 at 11:18 AM, Mike Belopuhov <[email protected]> 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?
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 09:24:09 -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,9 @@ 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 = pfsync_expires(st, ntohl(sp->expire),
+ sp->timeout);
- st->expire = ntohl(sp->expire) + time_second;
st->direction = sp->direction;
st->log = sp->log;
st->timeout = sp->timeout;
@@ -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];
+ 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;
+ }
+ result = time_second - timeout + expire;
+ if (end && states > start && start < end) {
+ if (states < end)
+ return (result + timeout * (end - states) /
+ (end - start));
+ else
+ return (time_second);
+ }
+
+ return (result);
}