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);
 }

Reply via email to