Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Nov 2018 14:32:44 +0100
From:      Andreas Longwitz <longwitz@incore.de>
To:        Konstantin Belousov <kib@freebsd.org>
Cc:        Kristof Provost <kp@FreeBSD.org>, Gleb Smirnoff <glebius@freebsd.org>,  freebsd-pf@freebsd.org
Subject:   Re: rdr pass for proto tcp sometimes creates states with expire time zero and so breaking connections
Message-ID:  <5BF169FC.2080508@incore.de>
In-Reply-To: <20181114070555.GK2378@kib.kiev.ua>
References:  <5BC51424.5000309@incore.de> <C4D1F141-2979-4103-957F-F0314637D978@sigsegv.be> <5BD45882.1000207@incore.de> <D5EEA773-1F0F-4FA0-A39A-486EE323907D@sigsegv.be> <5BEB3B9A.9080402@incore.de> <9004F62C-D1DC-4CFA-93A1-67E981274831@FreeBSD.org> <20181114070555.GK2378@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help

Thank you all for explanation how counter(9) works in detail.

> A single CPU instruction is atomic by definition, with regards to the CPU.
> A preemption can not happen in a middle of instruction. What the "lock"
> prefix does is memory locking to avoid unlocked parallel access to the
> same address by different CPUs.

OK, my view of "atomic" in this context was wrong.

> No, it does not look correct.  The only atomicity guarantee that is required
> from the counter.h inc and zero methods are atomicity WRT context switches.
> The instructions are always executed on the CPU which owns the PCPU element
> in the counter array, and since the update is executed as single instruction,
> it does not require more expensive cache line lock AKA LOCK prefix.  This
> is the main feature of the counters on x86.
> 
> It might read bogus value when fetching the counter but counter.h KPI only
> guarantee is that the readouts are mostly correct.  If you have systematically
> wrong value always read, there is probably something different going on.

On one of my two failing servers I have eliminated all "rdr pass" rules,
so counter(9) is not used at the moment for pf_default_rule.states_cur.
Using DTrace I can see the negative value -49 for this counter:


CPU     ID                    FUNCTION:NAME
  3      1                           :BEGIN
        feature=bfebfbff, ncpus=4
        pf_default_rule.states_cur=0xc82cb3c8
        0xc82cb3c8: counter0=0x00000000007bd25b
        0xc82cb7c8: counter1=0xffffffffffd32262
        0xc82cbbc8: counter2=0xffffffffffd87de1
        0xc82cbfc8: counter3=0xffffffffffd88d31
                    counter =0xffffffffffffffcf

On my other concerned server I have introduces a panic call as soon as
the counter value returned by counter_u64_fetch() in pf_state_expires()
will become negative. So I will wait for the panic and hope for more
information from the kerneldump.

There is one unusual configuration on the two servers: they use pf and
ipfw/ipdivert at once. The reason for this is my use of natd for
incoming ftp requests to my ftp server, pf handles all the other
traffic. This configuration is a little bit tricky but works correct for
many years.
One exception was recently a problem with a buggy remote ftp client I
had to debug. During this period I had to restart/reload ipfw and natd a
couple of times. Because pf also has a reference to ipdivert, perhaps
there is a hidden interaction with the expire problem of pf.

Annotation: the buggy ftp client revealed a problem in natd (PR 230755).

Regards,
Andreas






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5BF169FC.2080508>