* [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add().
@ 2025-10-21 13:39 Andrii Melnychenko
2025-10-21 13:39 ` [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack Andrii Melnychenko
2025-10-21 14:35 ` [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Florian Westphal
0 siblings, 2 replies; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-21 13:39 UTC (permalink / raw)
To: pablo, kadlec, fw, phil
Cc: davem, edumazet, kuba, pabeni, horms, netfilter-devel, coreteam,
netdev, linux-kernel
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 }
}
}
```
Connecting the client:
```
# ftp 192.168.100.1
Connected to 192.168.100.1.
220 Welcome to my FTP server.
Name (192.168.100.1:dev): user
331 Username ok, send password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> epsv
EPSV/EPRT on IPv4 off.
EPSV/EPRT on IPv6 off.
ftp> ls
227 Entering passive mode (192,168,100,1,209,129).
421 Service not available, remote server has closed connection.
```
Kernel logs:
```
Oct 16 10:24:37 vyos kernel: nf_conntrack_ftp: ftp: Conntrackinfo = 2
Oct 16 10:24:37 vyos kernel: nf_conntrack_ftp: ftp: dataoff(60) >= skblen(60)
Oct 16 10:24:37 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:37 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Oct 16 10:24:37 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:38 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Oct 16 10:24:38 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:38 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 33
Oct 16 10:24:38 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 33
Oct 16 10:24:38 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 8
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 8
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 23
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 23
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 19
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 19
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 25
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 25
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 133
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 133
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 15
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 15
Oct 16 10:24:40 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 51
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: Pattern matches!
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: Match succeeded!
Oct 16 10:24:44 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,13,2,209,129' (20 bytes at 2149072380)
Oct 16 10:24:44 vyos kernel: ------------[ cut here ]------------
Oct 16 10:24:44 vyos kernel: Missing nfct_seqadj_ext_add() setup call
Oct 16 10:24:44 vyos kernel: WARNING: CPU: 1 PID: 0 at net/netfilter/nf_conntrack_seqadj.c:41 nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: Modules linked in: nf_nat_ftp(E) nft_nat(E) nf_conntrack_ftp(E) af_packet(E) nft_ct(E) nft_chain_nat(E) nf_nat(E) nf_tables(E) nfnetlink_cthelper(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) nfnetlink(E) binfmt_misc(E) intel_rapl_common(E) crct10dif_pclmul(E) crc32_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) iTCO_wdt(E) iTCO_vendor_support(E) button(E) virtio_console(E) virtio_balloon(E) pcspkr(E) evdev(E) tcp_bbr(E) sch_fq_codel(E) mpls_iptunnel(E) mpls_router(E) ip_tunnel(E) br_netfilter(E) bridge(E) stp(E) llc(E) fuse(E) efi_pstore(E) configfs(E) virtio_rng(E) rng_core(E) ip_tables(E) x_tables(E) autofs4(E) usb_storage(E) ohci_hcd(E) uhci_hcd(E) ehci_hcd(E) sd_mod(E) squashfs(E) lz4_decompress(E) loop(E) overlay(E) ext4(E) crc16(E) mbcache(E) jbd2(E) nls_cp437(E) vfat(E) fat(E) efivarfs(E) nls_ascii(E) hid_generic(E) usbhid(E) hid(E) virtio_net(E) net_failover(E) virtio_blk(E) failover(E) ahci(E) libahci(E)
Oct 16 10:24:44 vyos kernel: crc32c_intel(E) i2c_i801(E) i2c_smbus(E) libata(E) lpc_ich(E) scsi_mod(E) scsi_common(E) xhci_pci(E) xhci_hcd(E) virtio_pci(E) virtio_pci_legacy_dev(E) virtio_pci_modern_dev(E) virtio(E) virtio_ring(E)
Oct 16 10:24:44 vyos kernel: CPU: 1 PID: 0 Comm: swapper/1 Tainted: G E 6.6.108-vyos #1
Oct 16 10:24:44 vyos kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
Oct 16 10:24:44 vyos kernel: RIP: 0010:nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: Code: ea 44 89 20 89 50 08 eb db 45 85 ed 74 de 80 3d 51 6d 00 00 00 75 d5 48 c7 c7 68 57 ad c0 c6 05 41 6d 00 00 01 e8 71 28 dd dc <0f> 0b eb be be 02 00 00 00 e8 63 fc ff ff 48 89 c3 e9 66 ff ff ff
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c00e8910 EFLAGS: 00010286
Oct 16 10:24:44 vyos kernel: RAX: 0000000000000000 RBX: 0000000000000014 RCX: 000000000000083f
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 00000000000000f6 RDI: 000000000000083f
Oct 16 10:24:44 vyos kernel: RBP: ffff89387978fb00 R08: 0000000000000000 R09: ffff9a66c00e87a8
Oct 16 10:24:44 vyos kernel: R10: 0000000000000003 R11: ffffffff9ecbab08 R12: ffff89387978fb00
Oct 16 10:24:44 vyos kernel: R13: 0000000000000001 R14: ffff893872e18862 R15: ffff893842f8c700
Oct 16 10:24:44 vyos kernel: FS: 0000000000000000(0000) GS:ffff893bafc80000(0000) knlGS:0000000000000000
Oct 16 10:24:44 vyos kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 16 10:24:44 vyos kernel: CR2: 000055fbc64ec690 CR3: 000000011de22001 CR4: 0000000000370ee0
Oct 16 10:24:44 vyos kernel: Call Trace:
Oct 16 10:24:44 vyos kernel: <IRQ>
Oct 16 10:24:44 vyos kernel: __nf_nat_mangle_tcp_packet+0x100/0x160 [nf_nat]
Oct 16 10:24:44 vyos kernel: nf_nat_ftp+0x142/0x280 [nf_nat_ftp]
Oct 16 10:24:44 vyos kernel: ? kmem_cache_alloc+0x157/0x290
Oct 16 10:24:44 vyos kernel: ? help+0x4d1/0x880 [nf_conntrack_ftp]
Oct 16 10:24:44 vyos kernel: help+0x4d1/0x880 [nf_conntrack_ftp]
Oct 16 10:24:44 vyos kernel: ? nf_confirm+0x122/0x2e0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: nf_confirm+0x122/0x2e0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: nf_hook_slow+0x3c/0xb0
Oct 16 10:24:44 vyos kernel: ip_output+0xb6/0xf0
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_finish_output+0x10/0x10
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv_finish+0x90/0xa0
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv+0x190/0x220
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_rcv_finish+0x10/0x10
Oct 16 10:24:44 vyos kernel: ip_list_rcv+0x134/0x160
Oct 16 10:24:44 vyos kernel: __netif_receive_skb_list_core+0x299/0x2c0
Oct 16 10:24:44 vyos kernel: netif_receive_skb_list_internal+0x1a7/0x2d0
Oct 16 10:24:44 vyos kernel: napi_complete_done+0x69/0x1a0
Oct 16 10:24:44 vyos kernel: virtnet_poll+0x3c0/0x540 [virtio_net]
Oct 16 10:24:44 vyos kernel: __napi_poll+0x26/0x1a0
Oct 16 10:24:44 vyos kernel: net_rx_action+0x141/0x2c0
Oct 16 10:24:44 vyos kernel: ? lock_timer_base+0x5c/0x80
Oct 16 10:24:44 vyos kernel: handle_softirqs+0xd5/0x280
Oct 16 10:24:44 vyos kernel: __irq_exit_rcu+0x95/0xb0
Oct 16 10:24:44 vyos kernel: common_interrupt+0x7a/0xa0
Oct 16 10:24:44 vyos kernel: </IRQ>
Oct 16 10:24:44 vyos kernel: <TASK>
Oct 16 10:24:44 vyos kernel: asm_common_interrupt+0x22/0x40
Oct 16 10:24:44 vyos kernel: RIP: 0010:pv_native_safe_halt+0xb/0x10
Oct 16 10:24:44 vyos kernel: Code: 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 90 0f 00 2d 29 9a 3e 00 fb f4 <c3> cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c009bed8 EFLAGS: 00000252
Oct 16 10:24:44 vyos kernel: RAX: ffff893bafcaaca8 RBX: 0000000000000001 RCX: 0000000000000001
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 0000000000000083 RDI: 0000000000064cec
Oct 16 10:24:44 vyos kernel: RBP: ffff8938401f2200 R08: 0000000000000001 R09: 0000000000000000
Oct 16 10:24:44 vyos kernel: R10: 000000000001ffc0 R11: 0000000000000000 R12: 0000000000000000
Oct 16 10:24:44 vyos kernel: R13: 0000000000000000 R14: ffff8938401f2200 R15: 0000000000000000
Oct 16 10:24:44 vyos kernel: default_idle+0x5/0x20
Oct 16 10:24:44 vyos kernel: default_idle_call+0x28/0xb0
Oct 16 10:24:44 vyos kernel: do_idle+0x1ec/0x230
Oct 16 10:24:44 vyos kernel: cpu_startup_entry+0x21/0x30
Oct 16 10:24:44 vyos kernel: start_secondary+0x11a/0x140
Oct 16 10:24:44 vyos kernel: secondary_startup_64_no_verify+0x178/0x17b
Oct 16 10:24:44 vyos kernel: </TASK>
Oct 16 10:24:44 vyos kernel: ---[ end trace 0000000000000000 ]---
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 51
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: Pattern matches!
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: Match succeeded!
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,13,2,209,129' (20 bytes at 2149072380)
Oct 16 10:24:45 vyos kernel: nf_conntrack_ftp: ftp: dataoff(40) >= skblen(40)
```
According to callstack, despite installing nf_nat_follow_master() helper,
the nfct_seqadj() call comes almost immediately after, before any
potential setups on already confirmed conntrack.
```
net/netfilter/nf_conntrack_proto.c: nf_confirm()
net/netfilter/nf_conntrack_ftp.c: help()
nf_ct_expect_init()
nf_nat_ftp()
net/netfilter/nf_nat_ftp.c: nf_nat_ftp()
exp->expectfn = nf_nat_follow_master;
nf_nat_mangle_tcp_packet()
net/netfilter/nf_nat_helper.c: __nf_nat_mangle_tcp_packet()
nf_ct_seqadj_set()
net/netfilter/nf_conntrack_seqadj.c: nf_ct_seqadj_set()
if (unlikely(!seqadj)) {
WARN_ONCE(1, "Missing nfct_seqadj_ext_add() setup call\n");
return 0;
}
```
Changes since v2:
* the "fix" moved from nf_conntrack_ftp to nft_ct
Changes since v1:
* fixed build, added missed header
Andrii Melnychenko (1):
nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
net/netfilter/nft_ct.c | 4 ++++
1 file changed, 4 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-21 13:39 [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Andrii Melnychenko
@ 2025-10-21 13:39 ` Andrii Melnychenko
2025-10-21 14:34 ` Florian Westphal
2025-10-21 14:35 ` [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Florian Westphal
1 sibling, 1 reply; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-21 13:39 UTC (permalink / raw)
To: pablo, kadlec, fw, phil
Cc: davem, edumazet, kuba, pabeni, horms, netfilter-devel, coreteam,
netdev, linux-kernel
There is an issue with the missed seqadj extension for NAT'ed
conntrack setup with nft. Sequence adjustment may be required
for FTP traffic with PASV/EPSV modes.
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:
```
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 }
}
}
```
Connecting the client:
```
Connected to 192.168.100.1.
220 Welcome to my FTP server.
Name (192.168.100.1:dev): user
331 Username ok, send password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> epsv
EPSV/EPRT on IPv4 off.
EPSV/EPRT on IPv6 off.
ftp> ls
227 Entering passive mode (192,168,100,1,209,129).
421 Service not available, remote server has closed connection.
```
Kernel logs:
```
Oct 16 10:24:44 vyos kernel: Missing nfct_seqadj_ext_add() setup call
Oct 16 10:24:44 vyos kernel: WARNING: CPU: 1 PID: 0 at net/netfilter/nf_conntrack_seqadj.c:41 nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: Modules linked in: nf_nat_ftp(E) nft_nat(E) nf_conntrack_ftp(E) af_packet(E) nft_ct(E) nft_chain_nat(E) nf_nat(E) nf_tables(E) nfnetlink_cthelper(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) nfnetlink(E) binfmt_misc(E) intel_rapl_common(E) crct10dif_pclmul(E) crc32_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) iTCO_wdt(E) iTCO_vendor_support(E) button(E) virtio_console(E) virtio_balloon(E) pcspkr(E) evdev(E) tcp_bbr(E) sch_fq_codel(E) mpls_iptunnel(E) mpls_router(E) ip_tunnel(E) br_netfilter(E) bridge(E) stp(E) llc(E) fuse(E) efi_pstore(E) configfs(E) virtio_rng(E) rng_core(E) ip_tables(E) x_tables(E) autofs4(E) usb_storage(E) ohci_hcd(E) uhci_hcd(E) ehci_hcd(E) sd_mod(E) squashfs(E) lz4_decompress(E) loop(E) overlay(E) ext4(E) crc16(E) mbcache(E) jbd2(E) nls_cp437(E) vfat(E) fat(E) efivarfs(E) nls_ascii(E) hid_generic(E) usbhid(E) hid(E) virtio_net(E) net_failover(E) virtio_blk(E) failover(E) ahci(E) libahci(E)
Oct 16 10:24:44 vyos kernel: crc32c_intel(E) i2c_i801(E) i2c_smbus(E) libata(E) lpc_ich(E) scsi_mod(E) scsi_common(E) xhci_pci(E) xhci_hcd(E) virtio_pci(E) virtio_pci_legacy_dev(E) virtio_pci_modern_dev(E) virtio(E) virtio_ring(E)
Oct 16 10:24:44 vyos kernel: CPU: 1 PID: 0 Comm: swapper/1 Tainted: G E 6.6.108-vyos #1
Oct 16 10:24:44 vyos kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
Oct 16 10:24:44 vyos kernel: RIP: 0010:nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: Code: ea 44 89 20 89 50 08 eb db 45 85 ed 74 de 80 3d 51 6d 00 00 00 75 d5 48 c7 c7 68 57 ad c0 c6 05 41 6d 00 00 01 e8 71 28 dd dc <0f> 0b eb be be 02 00 00 00 e8 63 fc ff ff 48 89 c3 e9 66 ff ff ff
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c00e8910 EFLAGS: 00010286
Oct 16 10:24:44 vyos kernel: RAX: 0000000000000000 RBX: 0000000000000014 RCX: 000000000000083f
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 00000000000000f6 RDI: 000000000000083f
Oct 16 10:24:44 vyos kernel: RBP: ffff89387978fb00 R08: 0000000000000000 R09: ffff9a66c00e87a8
Oct 16 10:24:44 vyos kernel: R10: 0000000000000003 R11: ffffffff9ecbab08 R12: ffff89387978fb00
Oct 16 10:24:44 vyos kernel: R13: 0000000000000001 R14: ffff893872e18862 R15: ffff893842f8c700
Oct 16 10:24:44 vyos kernel: FS: 0000000000000000(0000) GS:ffff893bafc80000(0000) knlGS:0000000000000000
Oct 16 10:24:44 vyos kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 16 10:24:44 vyos kernel: CR2: 000055fbc64ec690 CR3: 000000011de22001 CR4: 0000000000370ee0
Oct 16 10:24:44 vyos kernel: Call Trace:
Oct 16 10:24:44 vyos kernel: <IRQ>
Oct 16 10:24:44 vyos kernel: __nf_nat_mangle_tcp_packet+0x100/0x160 [nf_nat]
Oct 16 10:24:44 vyos kernel: nf_nat_ftp+0x142/0x280 [nf_nat_ftp]
Oct 16 10:24:44 vyos kernel: ? kmem_cache_alloc+0x157/0x290
Oct 16 10:24:44 vyos kernel: ? help+0x4d1/0x880 [nf_conntrack_ftp]
Oct 16 10:24:44 vyos kernel: help+0x4d1/0x880 [nf_conntrack_ftp]
Oct 16 10:24:44 vyos kernel: ? nf_confirm+0x122/0x2e0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: nf_confirm+0x122/0x2e0 [nf_conntrack]
Oct 16 10:24:44 vyos kernel: nf_hook_slow+0x3c/0xb0
Oct 16 10:24:44 vyos kernel: ip_output+0xb6/0xf0
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_finish_output+0x10/0x10
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv_finish+0x90/0xa0
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv+0x190/0x220
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_rcv_finish+0x10/0x10
Oct 16 10:24:44 vyos kernel: ip_list_rcv+0x134/0x160
Oct 16 10:24:44 vyos kernel: __netif_receive_skb_list_core+0x299/0x2c0
Oct 16 10:24:44 vyos kernel: netif_receive_skb_list_internal+0x1a7/0x2d0
Oct 16 10:24:44 vyos kernel: napi_complete_done+0x69/0x1a0
Oct 16 10:24:44 vyos kernel: virtnet_poll+0x3c0/0x540 [virtio_net]
Oct 16 10:24:44 vyos kernel: __napi_poll+0x26/0x1a0
Oct 16 10:24:44 vyos kernel: net_rx_action+0x141/0x2c0
Oct 16 10:24:44 vyos kernel: ? lock_timer_base+0x5c/0x80
Oct 16 10:24:44 vyos kernel: handle_softirqs+0xd5/0x280
Oct 16 10:24:44 vyos kernel: __irq_exit_rcu+0x95/0xb0
Oct 16 10:24:44 vyos kernel: common_interrupt+0x7a/0xa0
Oct 16 10:24:44 vyos kernel: </IRQ>
Oct 16 10:24:44 vyos kernel: <TASK>
Oct 16 10:24:44 vyos kernel: asm_common_interrupt+0x22/0x40
Oct 16 10:24:44 vyos kernel: RIP: 0010:pv_native_safe_halt+0xb/0x10
Oct 16 10:24:44 vyos kernel: Code: 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 90 0f 00 2d 29 9a 3e 00 fb f4 <c3> cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c009bed8 EFLAGS: 00000252
Oct 16 10:24:44 vyos kernel: RAX: ffff893bafcaaca8 RBX: 0000000000000001 RCX: 0000000000000001
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 0000000000000083 RDI: 0000000000064cec
Oct 16 10:24:44 vyos kernel: RBP: ffff8938401f2200 R08: 0000000000000001 R09: 0000000000000000
Oct 16 10:24:44 vyos kernel: R10: 000000000001ffc0 R11: 0000000000000000 R12: 0000000000000000
Oct 16 10:24:44 vyos kernel: R13: 0000000000000000 R14: ffff8938401f2200 R15: 0000000000000000
Oct 16 10:24:44 vyos kernel: default_idle+0x5/0x20
Oct 16 10:24:44 vyos kernel: default_idle_call+0x28/0xb0
Oct 16 10:24:44 vyos kernel: do_idle+0x1ec/0x230
Oct 16 10:24:44 vyos kernel: cpu_startup_entry+0x21/0x30
Oct 16 10:24:44 vyos kernel: start_secondary+0x11a/0x140
Oct 16 10:24:44 vyos kernel: secondary_startup_64_no_verify+0x178/0x17b
Oct 16 10:24:44 vyos kernel: </TASK>
```
Fixes: 1a64edf54f55 ("netfilter: nft_ct: add helper set support")
Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
---
net/netfilter/nft_ct.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index d526e69a2..73d0590fb 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -22,6 +22,7 @@
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_expect.h>
+#include <net/netfilter/nf_conntrack_seqadj.h>
struct nft_ct_helper_obj {
struct nf_conntrack_helper *helper4;
@@ -1173,6 +1174,9 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
if (help) {
rcu_assign_pointer(help->helper, to_assign);
set_bit(IPS_HELPER_BIT, &ct->status);
+
+ if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
+ nfct_seqadj_ext_add(ct);
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-21 13:39 ` [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack Andrii Melnychenko
@ 2025-10-21 14:34 ` Florian Westphal
2025-10-21 16:24 ` Andrii Melnychenko
2025-10-22 0:11 ` Pablo Neira Ayuso
0 siblings, 2 replies; 13+ messages in thread
From: Florian Westphal @ 2025-10-21 14:34 UTC (permalink / raw)
To: Andrii Melnychenko
Cc: pablo, kadlec, phil, davem, edumazet, kuba, pabeni, horms,
netfilter-devel, coreteam, netdev, linux-kernel
Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
>
> struct nft_ct_helper_obj {
> struct nf_conntrack_helper *helper4;
> @@ -1173,6 +1174,9 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
> if (help) {
> rcu_assign_pointer(help->helper, to_assign);
> set_bit(IPS_HELPER_BIT, &ct->status);
> +
> + if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
> + nfct_seqadj_ext_add(ct);
Any reason why you removed the drop logic of earlier versions?
I think this needs something like this:
if (!nfct_seqadj_ext_add(ct))
regs->verdict.code = NF_DROP;
so client will eventually retransmit the connection request.
I can also mangle this locally, let me know.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-21 14:34 ` Florian Westphal
@ 2025-10-21 16:24 ` Andrii Melnychenko
2025-10-21 16:34 ` Florian Westphal
2025-10-22 0:11 ` Pablo Neira Ayuso
1 sibling, 1 reply; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-21 16:24 UTC (permalink / raw)
To: Florian Westphal
Cc: pablo, kadlec, phil, davem, edumazet, kuba, pabeni, horms,
netfilter-devel, coreteam, netdev, linux-kernel
Hi all,
> I think this needs something like this:
>
> if (!nfct_seqadj_ext_add(ct))
> regs->verdict.code = NF_DROP;
Okay - I'll update it. I'm planning a proper test.
Apparently, I need to provide a simple test FTP server/client, not
fully functional,
but sufficient to "trigger" nf_conntrack_ftp.
On Tue, Oct 21, 2025 at 4:34 PM Florian Westphal <fw@strlen.de> wrote:
>
> Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> >
> > struct nft_ct_helper_obj {
> > struct nf_conntrack_helper *helper4;
> > @@ -1173,6 +1174,9 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
> > if (help) {
> > rcu_assign_pointer(help->helper, to_assign);
> > set_bit(IPS_HELPER_BIT, &ct->status);
> > +
> > + if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
> > + nfct_seqadj_ext_add(ct);
>
> Any reason why you removed the drop logic of earlier versions?
>
> I think this needs something like this:
>
> if (!nfct_seqadj_ext_add(ct))
> regs->verdict.code = NF_DROP;
>
> so client will eventually retransmit the connection request.
>
> I can also mangle this locally, let me know.
--
Andrii Melnychenko
Phone +1 844 980 2188
Email a.melnychenko@vyos.io
Website vyos.io
linkedin.com/company/vyos
vyosofficial
x.com/vyos_dev
reddit.com/r/vyos/
youtube.com/@VyOSPlatform
Subscribe to Our Blog Keep up with VyOS
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-21 16:24 ` Andrii Melnychenko
@ 2025-10-21 16:34 ` Florian Westphal
0 siblings, 0 replies; 13+ messages in thread
From: Florian Westphal @ 2025-10-21 16:34 UTC (permalink / raw)
To: Andrii Melnychenko
Cc: pablo, kadlec, phil, davem, edumazet, kuba, pabeni, horms,
netfilter-devel, coreteam, netdev, linux-kernel
Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> Hi all,
>
> > I think this needs something like this:
> >
> > if (!nfct_seqadj_ext_add(ct))
> > regs->verdict.code = NF_DROP;
>
> Okay - I'll update it. I'm planning a proper test.
>
> Apparently, I need to provide a simple test FTP server/client, not
> fully functional,
> but sufficient to "trigger" nf_conntrack_ftp.
Argh, I forgot we do have an ftp test case in the nftables repo, even
with NAT.
tests/shell/testcases/packetpath/nat_ftp
in nftables.git repo from git.netfilter.org.
So it would be easier to extend that instead of a new kselftest for the
kernel.
From a short glance I guess it works because the address rewrite doesn't
need to expand the packet, else this should have failed and found this
bug...
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-21 14:34 ` Florian Westphal
2025-10-21 16:24 ` Andrii Melnychenko
@ 2025-10-22 0:11 ` Pablo Neira Ayuso
2025-10-22 11:14 ` Florian Westphal
1 sibling, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2025-10-22 0:11 UTC (permalink / raw)
To: Florian Westphal
Cc: Andrii Melnychenko, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
On Tue, Oct 21, 2025 at 04:34:46PM +0200, Florian Westphal wrote:
> Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> >
> > struct nft_ct_helper_obj {
> > struct nf_conntrack_helper *helper4;
> > @@ -1173,6 +1174,9 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
> > if (help) {
> > rcu_assign_pointer(help->helper, to_assign);
> > set_bit(IPS_HELPER_BIT, &ct->status);
> > +
> > + if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
> > + nfct_seqadj_ext_add(ct);
>
> Any reason why you removed the drop logic of earlier versions?
>
> I think this needs something like this:
>
> if (!nfct_seqadj_ext_add(ct))
> regs->verdict.code = NF_DROP;
>
> so client will eventually retransmit the connection request.
>
> I can also mangle this locally, let me know.
BTW, this fixes DNAT case, but SNAT case is still broken because flag
is set at a later stage, right?
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-22 0:11 ` Pablo Neira Ayuso
@ 2025-10-22 11:14 ` Florian Westphal
2025-10-22 13:01 ` Andrii Melnychenko
0 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2025-10-22 11:14 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Andrii Melnychenko, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > so client will eventually retransmit the connection request.
> >
> > I can also mangle this locally, let me know.
>
> BTW, this fixes DNAT case, but SNAT case is still broken because flag
> is set at a later stage, right?
Hmm, why? nf_nat_setup_info() will add seqadj extension if a helper
is assigned. I only see two nat cases:
The helper is assigned, no NAT was requested.
Then, in postrouting, a NAT rule gets triggered.
nf_nat_setup_info() will add the seqadj extension for us.
This case doesn't need this patch. Broken scenario:
NAT rule gets triggered, no helper is assigned yet.
Then, 'helper set foo' rule gets triggered.
This case missed the seqadj extension add.
An alternative would be to reject 'helper set foo' rule add unless the
expression is called from prerouting or output with a priority that is
after conntrack but before nat.
But its more risky change, it would surely break some setups.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-22 11:14 ` Florian Westphal
@ 2025-10-22 13:01 ` Andrii Melnychenko
2025-10-23 12:28 ` Andrii Melnychenko
0 siblings, 1 reply; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-22 13:01 UTC (permalink / raw)
To: Florian Westphal
Cc: Pablo Neira Ayuso, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Hi all,
> BTW, this fixes DNAT case, but SNAT case is still broken because flag
> is set at a later stage, right?
I've checked SNAT with the "PORT" FTP command - didn't reproduce the bug.
I assume that `nft_nat_eval()` -> `nf_nat_setup_info()` sets up seqadj
for the SNAT case.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-22 13:01 ` Andrii Melnychenko
@ 2025-10-23 12:28 ` Andrii Melnychenko
2025-10-23 12:42 ` Florian Westphal
0 siblings, 1 reply; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-23 12:28 UTC (permalink / raw)
To: Florian Westphal
Cc: Pablo Neira Ayuso, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Hi all,
I've taken a look at the `nat_ftp` test from nftables. It actually
passes fine, I've tried to modify the test, add IPv4 and force
PASV/PORT mode - everything works.
Currently, I'm studying the difference between NFT rulesets.
Primarily, I'm testing on 2 kernels: 6.6.108 and 6.14.0-33.
On Wed, Oct 22, 2025 at 3:01 PM Andrii Melnychenko
<a.melnychenko@vyos.io> wrote:
>
> Hi all,
>
> > BTW, this fixes DNAT case, but SNAT case is still broken because flag
> > is set at a later stage, right?
>
> I've checked SNAT with the "PORT" FTP command - didn't reproduce the bug.
> I assume that `nft_nat_eval()` -> `nf_nat_setup_info()` sets up seqadj
> for the SNAT case.
--
Andrii Melnychenko
Phone +1 844 980 2188
Email a.melnychenko@vyos.io
Website vyos.io
linkedin.com/company/vyos
vyosofficial
x.com/vyos_dev
reddit.com/r/vyos/
youtube.com/@VyOSPlatform
Subscribe to Our Blog Keep up with VyOS
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-23 12:28 ` Andrii Melnychenko
@ 2025-10-23 12:42 ` Florian Westphal
2025-10-24 12:26 ` Andrii Melnychenko
0 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2025-10-23 12:42 UTC (permalink / raw)
To: Andrii Melnychenko
Cc: Pablo Neira Ayuso, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> I've taken a look at the `nat_ftp` test from nftables. It actually
> passes fine, I've tried to modify the test, add IPv4 and force
> PASV/PORT mode - everything works.
> Currently, I'm studying the difference between NFT rulesets.
> Primarily, I'm testing on 2 kernels: 6.6.108 and 6.14.0-33.
I think its this:
chain POST-srcnat {
type nat hook postrouting priority srcnat; policy accept;
ip6 daddr ${ip_sr} ip6 nexthdr tcp tcp dport 21 counter snat ip6 to [${ip_rs}]:16500
}
This sets up snat which calls nf_nat_setup_info which adds the
seqadj extension.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-23 12:42 ` Florian Westphal
@ 2025-10-24 12:26 ` Andrii Melnychenko
2025-10-24 12:58 ` Florian Westphal
0 siblings, 1 reply; 13+ messages in thread
From: Andrii Melnychenko @ 2025-10-24 12:26 UTC (permalink / raw)
To: Florian Westphal
Cc: Pablo Neira Ayuso, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Hi everyone,
On Thu, Oct 23, 2025 at 2:42 PM Florian Westphal <fw@strlen.de> wrote:
>
> Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> > I've taken a look at the `nat_ftp` test from nftables. It actually
> > passes fine, I've tried to modify the test, add IPv4 and force
> > PASV/PORT mode - everything works.
> > Currently, I'm studying the difference between NFT rulesets.
> > Primarily, I'm testing on 2 kernels: 6.6.108 and 6.14.0-33.
>
> I think its this:
> chain POST-srcnat {
> type nat hook postrouting priority srcnat; policy accept;
> ip6 daddr ${ip_sr} ip6 nexthdr tcp tcp dport 21 counter snat ip6 to [${ip_rs}]:16500
> }
>
It is! I've compared the ruleset and found that the SNAT rule differs slightly.
In my case, it's something like this:
```
ip6 daddr ${ip_cr} ip6 nexthdr tcp tcp sport 21 counter snat ip6 to ${ip_rc}
```
So, for example:
+-------------------+ +----------------------------------+
| FTP: 192.168.13.2 | <-> | NAT: 192.168.13.3, 192.168.100.1 |
+-------------------+ +----------------------------------+
|
+-----------------------+
| Client: 192.168.100.2 |
+-----------------------+
The FTP server is "behind" the router. So the client needs to connect
to the router.
With a ruleset like this:
```
table ip nat {
ct helper ftp_helper {
type "ftp" protocol tcp
l3proto ip
}
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 }
}
chain filter_prerouting {
type filter hook prerouting priority 350; policy accept;
tcp dport 21 ct helper set "ftp_helper"
}
}
```
Client has to connect to the router (192.168.100.2 -> 192.168.100.2),
while the FTP server would receive the connection from the client
(192.168.100.2 -> 192.168.33.2).
So the connection hits SNAT when it's already established and confirmed.
> This sets up snat which calls nf_nat_setup_info which adds the
> seqadj extension.
So, we still need to add seqadj allocation for DNAT.
I will propose a new patch v4 with `regs->verdict.code = NF_DROP;`.
And later, I can provide a new ruleset for tests in `nft_ftp` for `nftables`.
Any suggestions?
--
Andrii Melnychenko
Phone +1 844 980 2188
Email a.melnychenko@vyos.io
Website vyos.io
linkedin.com/company/vyos
vyosofficial
x.com/vyos_dev
reddit.com/r/vyos/
youtube.com/@VyOSPlatform
Subscribe to Our Blog Keep up with VyOS
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack.
2025-10-24 12:26 ` Andrii Melnychenko
@ 2025-10-24 12:58 ` Florian Westphal
0 siblings, 0 replies; 13+ messages in thread
From: Florian Westphal @ 2025-10-24 12:58 UTC (permalink / raw)
To: Andrii Melnychenko
Cc: Pablo Neira Ayuso, kadlec, phil, davem, edumazet, kuba, pabeni,
horms, netfilter-devel, coreteam, netdev, linux-kernel
Andrii Melnychenko <a.melnychenko@vyos.io> wrote:
> Client has to connect to the router (192.168.100.2 -> 192.168.100.2),
> while the FTP server would receive the connection from the client
> (192.168.100.2 -> 192.168.33.2).
> So the connection hits SNAT when it's already established and confirmed.
>
> > This sets up snat which calls nf_nat_setup_info which adds the
> > seqadj extension.
>
> So, we still need to add seqadj allocation for DNAT.
> I will propose a new patch v4 with `regs->verdict.code = NF_DROP;`.
Yes, just resend your previous patch with the DROP added to force
rexmit rather than ending up with a non-working/stuck connection.
> And later, I can provide a new ruleset for tests in `nft_ftp` for `nftables`.
Thank you.
> Any suggestions?
You can send the bug fix now and followup with a different config later,
you can just extend the existing test case or, if you think your scenario
differs too much, add a new one.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add().
2025-10-21 13:39 [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Andrii Melnychenko
2025-10-21 13:39 ` [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack Andrii Melnychenko
@ 2025-10-21 14:35 ` Florian Westphal
1 sibling, 0 replies; 13+ messages in thread
From: Florian Westphal @ 2025-10-21 14:35 UTC (permalink / raw)
To: Andrii Melnychenko
Cc: pablo, kadlec, phil, davem, edumazet, kuba, pabeni, horms,
netfilter-devel, coreteam, netdev, linux-kernel
Andrii Melnychenko <a.melnychenko@vyos.io> 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.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-10-24 12:58 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-21 13:39 [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Andrii Melnychenko
2025-10-21 13:39 ` [PATCH v3 1/1] nft_ct: Added nfct_seqadj_ext_add() for NAT'ed conntrack Andrii Melnychenko
2025-10-21 14:34 ` Florian Westphal
2025-10-21 16:24 ` Andrii Melnychenko
2025-10-21 16:34 ` Florian Westphal
2025-10-22 0:11 ` Pablo Neira Ayuso
2025-10-22 11:14 ` Florian Westphal
2025-10-22 13:01 ` Andrii Melnychenko
2025-10-23 12:28 ` Andrii Melnychenko
2025-10-23 12:42 ` Florian Westphal
2025-10-24 12:26 ` Andrii Melnychenko
2025-10-24 12:58 ` Florian Westphal
2025-10-21 14:35 ` [PATCH v3 0/1] nf_conntrack_ftp: Added nfct_seqadj_ext_add() Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).