From: Florian Westphal <fw@strlen.de>
To: Phil Sutter <phil@nwl.cc>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>, netfilter-devel@vger.kernel.org
Subject: Re: [conntrack-tools] conntrack.8: Document --stats counters
Date: Fri, 17 Jul 2026 12:37:21 +0200 [thread overview]
Message-ID: <aloF4dOlN_XMWsFl@strlen.de> (raw)
In-Reply-To: <aln9W7xoIhKM7P4P@orbyte.nwl.cc>
Phil Sutter <phil@nwl.cc> wrote:
> Thanks for your feedback so far. What I don't like is how we all seem to
> reverse engineer meaning into the counter values. Maybe this is an
> opportunity to clarify what these counters *should* represent and with
> that in mind treat any deviation in the code as a bug which needs
> fixing.
Agreed.
> Since nf_conntrack_hash_check_insert is called from
> net/netfilter/nf_conntrack_bpf.c, too I'll put this as "Number of
> entries manually inserted (via netlink or eBPF)."
Oh, did not realize this was also called via ebpf.
> > oversized hash buckets should not be mentioned here, they have their own
> > counter. Should probably not increment both counters in kernel when it
> > happens.
>
> I see it incremented in three places:
>
> 1) nf_ct_resolve_clash
> - Increments 'drop' at the same time
> - This is the "clash resolution failure" case I mentioned
> - Happens either if nf_conntrack_l4proto does not set 'allow_clash' or
> both __nf_ct_resolve_clash and nf_ct_resolve_clash_harder fail
>
> 2) First spot in __nf_conntrack_confirm
> - Called "entry in dying state" by me above
> - AIUI, happens when confirming a conntrack entry (SYN-ACK?) for which
> nf_ct_is_dying() returns true
SYN, we only ever confirm the NEW / first packet of a flow.
> 3) Second spot in __nf_conntrack_confirm
> - Increments 'chaintoolong' at the same time
> - Happens if oversized hash bucket is encountered(?)
Yes.
> > Maybe: "Number of NEW connections dropped because of clashes with existing entry."?
> So this would be just #1 above. As a remedy, I would:
>
> - Remove the 'drop' increment in #1, make it *the* insert_failed counter
> case
> - Remove the 'insert_failed' increment from #3
No objections.
> But what about #2? Introduce a new counter? Increment 'drop' instead?
I'm not sure this can ever be true anymore (dying on unconfirmed).
I would leave it as-is. In both nf_ct_resolve_clash and this case there
is nothing the user could do. At least I can't think of anything.
> > Yes, I think we need to fix this in the kernel and not increment two
> > counters for the same reason.
> >
> > Drop should mostly mean "incomplete packet / out of memory".
>
> Hmm. Assuming we no longer increment it in nf_ct_resolve_clash, the
> following incrementers remain:
>
> 1) nf_conntrack_in
> - If resolve_normal_ct returns error, which happens only if
> init_conntrack returns -ENOMEM
>
> 2) nf_conntrack_in
> - Also increments 'invalid' counter
> - If nf_conntrack_handle_packet returned 0 (= NF_DROP), which seems
> to be a special case with TCP (added in commit 6b69fe0c73c0
> ("netfilter: nf_conntrack_tcp: fix endless loop"))
>
> 3) nf_confirm_cthelper
> - If TCP sequence number adjustment fails, which seems to happen only
> on ENOMEM, missing seqadj CT extension or malformed TCP packet
> (having a tcpopt header with invalid optlen)
>
> Maybe one should split #3 to increment 'invalid' upon invalid TCP option
> header?
Good idea.
> What about #2? Should this increment 'invalid' at all? It does
> not seem to indicate an invalid packet, but rather some internal
> corner-case, right?
Yes, I think its best to remove the invalid increment here.
> > > +.B early_drop
> > > +Number of packets dropped up front due to full table
> >
> > AFAICS its number of connections dropped because of a full table.
>
> This is incremented by early_drop() only, called by __nf_conntrack_alloc
> if a netns's conntrack table exceeds nf_conntrack_max. Am I getting this
> right and early_drop() tries to drop existing entries to free up space
> for the new one? I don't see any particular preference in
> early_drop_list(), is this just "best effort"? (I guess the system is
> under pressure and the goal is to resolve the situation as quickly as
> possible?)
Yes, it will attempt to remove another competing entry (not confirmed,
meaning short-lived UDP or TCP that did not progress past 3whs yet).
> > > +.B search_restart
> > > +Number of times a table lookup had to be restarted due to table reorg
> >
> > Not sure about this one. This is an implementation detail (SLAB_TYPESAFE_BY_RCU).
> > This can happen at any time when entry is removed from table and
> > other CPU is re-instantiating a new conection using the just-unlinked
> > entry.
>
> Ah, I see. Guess the comment in ____nf_conntrack_find misled me into
> believing this was about hash table reorgs.
>
> Maybe describe like this (which avoids too many internal details):
>
> "Number of table lookups which had to be restarted. Due to optimized
> storage reuse, a table lookup may occasionally find an already deleted
> entry. This is detected and remedied by restarting the search."
Maybe even more terse, e.g.
"Number of table lookups which had to be restarted. In rare cases a
lookup may encounter an already deleted entry which causes a
search restart."
Up to you, this is hard to explain without the implementation details,
the question would be "what does that counter tell me" and "what should
I do about this". And I have no answer. I thought about removing this
counter, but then this would allow to detect programming bugs (chain end
tag corrupted) for example.
Thanks for working on this!
prev parent reply other threads:[~2026-07-17 10:37 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-27 17:37 [conntrack-tools] conntrack.8: Document --stats counters Phil Sutter
2026-05-28 7:46 ` Florian Westphal
2026-07-17 10:00 ` Phil Sutter
2026-07-17 10:37 ` Florian Westphal [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aloF4dOlN_XMWsFl@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.