Subject: Re: [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add().

From: Florian Westphal <[email-masked]>
Date: Tue, 21 Oct 2025 16:35:47 +0200

Andrii Melnychenko <[email-masked]> wrote:
> There is an issue with FTP SNAT/DNAT. When the PASV/EPSV message is altered
> The sequence adjustment is required, and there is an issue that seqadj is
> not set up at that moment.
> 
> During the patch v2 discussion, it was decided to implement the fix
> in the nft_ct. Apparently, missed seqadj is the issue of nft nat helpers.
> The current fix would set up the seqadj extension for all NAT'ed conntrack
> helpers.
> 
> The easiest way to reproduce this issue is with PASV mode.
> Topoloy:
> ```
>  +-------------------+     +----------------------------------+
>  | FTP: 192.168.13.2 | <-> | NAT: 192.168.13.3, 192.168.100.1 |
>  +-------------------+     +----------------------------------+
>                                      |
>                          +-----------------------+
>                          | Client: 192.168.100.2 |
>                          +-----------------------+
> ```
> 
> nft ruleset:
> ```
> nft flush ruleset
> sudo nft add table inet ftp_nat
> sudo nft add ct helper inet ftp_nat ftp_helper { type \"ftp\" protocol tcp\; }
> sudo nft add chain inet ftp_nat prerouting { type filter hook prerouting priority 0 \; policy accept \; }
> sudo nft add rule inet ftp_nat prerouting tcp dport 21 ct state new ct helper set "ftp_helper"
> nft add table ip nat
> nft add chain ip nat prerouting { type nat hook prerouting priority dstnat \; policy accept \; }
> nft add chain ip nat postrouting { type nat hook postrouting priority srcnat \; policy accept \; }
> nft add rule ip nat prerouting tcp dport 21 dnat ip prefix to ip daddr map { 192.168.100.1 : 192.168.13.2/32 }
> nft add rule ip nat postrouting tcp sport 21 snat ip prefix to ip saddr map { 192.168.13.2 : 192.168.100.1/32 }
> 
> # nft -s list ruleset
> table inet ftp_nat {
>         ct helper ftp_helper {
>                 type "ftp" protocol tcp
>                 l3proto inet
>         }
> 
>         chain prerouting {
>                 type filter hook prerouting priority filter; policy accept;
>                 tcp dport 21 ct state new ct helper set "ftp_helper"
>         }
> }
> table ip nat {
>         chain prerouting {
>                 type nat hook prerouting priority dstnat; policy accept;
>                 tcp dport 21 dnat ip prefix to ip daddr map { 192.168.100.1 : 192.168.13.2/32 }
>         }
> 
>         chain postrouting {
>                 type nat hook postrouting priority srcnat; policy accept;
>                 tcp sport 21 snat ip prefix to ip saddr map { 192.168.13.2 : 192.168.100.1/32 }
>         }
> }
> 

Any chance you'd be willing to turn this into a selftest for
tools/testing/selftests/net/netfilter ?

I think it would add value.
Not a hard requirement of course.