Re: [PATCH nf] netfilter: flowtable: do not clear the offload bit twice

From: Pablo Neira Ayuso

Date: Tue Nov 03 2026 - 10:07:16 EST


On Tue, Nov 03, 2026 at 09:52:56AM +0000, João Silva via B4 Relay wrote:
> From: João Silva <jgc3silva@xxxxxxxxx>
>
> An expired hardware flow remains in the flowtable until its asynchronous
> hardware deletion completes. Teardown clears IPS_OFFLOAD_BIT, so a packet
> can create a replacement flow referencing the same conntrack entry while
> the old flow is still waiting for deletion.
>
> The next GC pass calls flow_offload_teardown() on the expired old flow
> again, clearing the replacement's offload bit. More packets can then
> create additional flows for the same conntrack entry. A pending hardware
> work item can also delay deletion and expose the same repeated teardown.
>
> Commit d2d31ea8cd80 ("netfilter: conntrack: fix erronous removal of
> offload bit") closed this window for software flows by unlinking them in
> the same GC pass and made the conntrack state fixup one-shot, but
> hardware flows stay linked until NF_FLOW_HW_DEAD is set.
>
> Make clearing IPS_OFFLOAD_BIT part of the existing one-time teardown
> transition, alongside the conntrack state fixup. Subsequent teardown calls
> must not alter the offload state now owned by a replacement flow.

Let's better target nf-next for this, this looks like LLM triggered
for correctness.

Thanks.

> Fixes: e5eaac2beb54 ("netfilter: flowtable: fix TCP flow teardown")
> Signed-off-by: João Silva <jgc3silva@xxxxxxxxx>
> ---
> net/netfilter/nf_flow_table_core.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
> index 0d72dc8ae47a..709b55b74cc7 100644
> --- a/net/netfilter/nf_flow_table_core.c
> +++ b/net/netfilter/nf_flow_table_core.c
> @@ -398,9 +398,11 @@ static void flow_offload_del(struct nf_flowtable *flow_table,
>
> void flow_offload_teardown(struct flow_offload *flow)
> {
> + if (test_and_set_bit(NF_FLOW_TEARDOWN, &flow->flags))
> + return;
> +
> clear_bit(IPS_OFFLOAD_BIT, &flow->ct->status);
> - if (!test_and_set_bit(NF_FLOW_TEARDOWN, &flow->flags))
> - flow_offload_fixup_ct(flow);
> + flow_offload_fixup_ct(flow);
> }
> EXPORT_SYMBOL_GPL(flow_offload_teardown);
>
>
> ---
> base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
> change-id: 20261103-flowtable-offload-bit-f15bfd1d38ed
>
> Best regards,
> --
> João Silva <jgc3silva@xxxxxxxxx>
>
>