Re: [PATCH net] netfilter: nf_dup_netdev: scrub duplicates to preserve the direct path
Pablo Neira Ayuso <[email protected]> Wed, 5 Aug 2026 10:24:33 +0200
| Newsgroups | gmane.linux.network,gmane.comp.security.firewalls.netfilter.devel |
|---|---|
| Message-ID | <anLzQeYulW2CQItC@chamomile> |
Hi, On Tue, Aug 04, 2026 at 10:11:50PM +0200, Alexandre Ferrieux wrote: > The nftables 'dup' action clones the skb with its full glory of > metadata, including references to its destination and conntrack > information. As a consequence, a link failure on the duplicate's > egress path ends up doing the same as it would for the direct path, > for example invalidating the original packet's destination, which > typically breaks all TCP connections to that address. > > In other words, the "dup" path has the potential to wreak havoc > in the direct path as a consequence of secondary link failures. This > is very bad behavior for a monitoring tool, which is the most > obvious application of 'dup'. Can you describe your use-case a bit and how it breaks? > This patch fixes all similar scenarii by calling skb_scrub_pkt() > on the clone, severing its link to precious direct-path state. This patch is targetted at the net tree, but nf.git is preferred. > Note: the second argument of skb_scrub_pkt(), the boolean "packet > is crossing netns", is intentionally set to 'false', as a 'true' > involves exaggerate scrubbing, e.g. of the timestamp, which a > monitoring 'dup' typically wants to preserve. Yes, the skb->mark should really remain in place for the duplication. As for the conntrack and dst, you have to explain what it breaks on your end. > Signed-off-by: Alexandre Ferrieux <[email protected]> > --- > net/netfilter/nf_dup_netdev.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c > index c6bd5c29bed6..0f47a2135955 100644 > --- a/net/netfilter/nf_dup_netdev.c > +++ b/net/netfilter/nf_dup_netdev.c > @@ -63,8 +63,10 @@ void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif) > return; > > skb = skb_clone(pkt->skb, GFP_ATOMIC); > - if (skb) > + if (skb) { > + skb_scrub_packet(skb, false); > nf_do_netdev_egress(skb, dev, nft_hook(pkt)); > + } > } > EXPORT_SYMBOL_GPL(nf_dup_netdev_egress); > > -- > 2.47.3 > >