Re: [PATCH nf v7 1/1] netfilter: nf_dup: preserve duplication guard across NFQUEUE
From: zihan xi
Date: Wed Oct 14 2026 - 07:15:23 EST
On Wed, Oct 14, 2026 at 6:40 PM Florian Westphal <fw@xxxxxxxxx> wrote:
>
> zihan xi <zihanx@xxxxxxxxxx> wrote:
> > Hi Florian,
> >
> > Thanks again for the review. I tested the simpler approach you suggested:
> > extending the local_bh_disable() / local_bh_enable() scope in
> > nf_reinject() to cover hook lookup, hook traversal, and okfn execution.
> > The experiment changed only nfnetlink_queue.c and built successfully
> > against nf.git main at ab699d296e06.
> >
> > I ran the IPv6 TEE/NFQUEUE reproducer in a 2-vCPU, 2-GiB QEMU guest
> > in a network namespace owned by a non-initial user namespace, with:
> >
> > QUEUE_COUNT=1
> > PAYLOAD=1
> > TEE_CLONES=1
> > panic_on_oom=0
> >
> > The bounded run reached 68,881 callback iterations in 6.700 seconds and
> > exited normally. No OOM, panic, Oops, BUG, or soft lockup was observed.
> > This was a bounded resource-consumption run, not an OOM or crash test.
> >
> > The reproducer continued executing the callback loop throughout the
> > bounded run, so extending the BH-disabled region alone does not address
> > this case. It protects against BH interference during nf_reinject(), but
> > it does not preserve current->in_nf_duplicate across the asynchronous
> > NFQUEUE verdict path: the original ip_local_out() or ip6_local_out()
> > call has already returned and cleared the task-local guard before
> > reinjection starts.
>
> Why? You'd store the current->in_nf_duplicate struct nf_queue_entry
> at queue time ("this skb is due to recursion via nf dup").
>
> Then, on reinject, you'd set current->in_nf_duplicate to the
> value stashed in struct nf_queue_entry so that if we were queued earlier
> from the recursion a potential further 'dup' would see current->in_nf_duplicate
> as true and skip next duplication round.
>
> I think one could add a 'DEBUG_NET_WARN_ONCE(current->in_nf_duplicate)'
> in nf_reinject, I don't see how it could be set on function entry.
>
> What did I miss?
Hi Florian,
I understand your suggestion now: save current->in_nf_duplicate in
struct nf_queue_entry when the packet is queued, then restore it before
nf_reinject() resumes hook traversal. I had focused on the BH-scope
change and missed this state-preservation approach.
I'll prototype this simpler direction, add the suggested
DEBUG_NET_WARN_ONCE(current->in_nf_duplicate) check at nf_reinject()
entry, and verify the flag's lifetime and cleanup, including requeueing
and all exit paths.
This approach is intended to address the IPv4/IPv6 duplication guard.
nft_dup_netdev uses a separate netdev xmit recursion counter, so
I'll review that path independently.
Best regards,
Zihan