Skip to content

Commit 8631bc5

Browse files
kernel: T6788: Added patch to fix sequence adjustment for FTP DNAT
The patch adds seqadj initialization for NATed conntrack. This fixes access to FTP servers "behind" the NAT router. The patch itself was proposed to the kernel and was accepted. In future versions it should be included into the kernel. Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
1 parent 6b9fe16 commit 8631bc5

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
From 0b00219cbd0e942dc2a2d86ecda52b7de4617227 Mon Sep 17 00:00:00 2001
2+
From: Andrii Melnychenko <a.melnychenko@vyos.io>
3+
Date: Tue, 14 Oct 2025 12:36:55 +0200
4+
Subject: [PATCH v4 1/1] nft_ct: Added nfct_seqadj_ext_add() for DNAT'ed
5+
conntrack.
6+
7+
There is an issue with the missed seqadj extension for NAT'ed
8+
conntrack setup with nft. Sequence adjustment may be required
9+
for FTP traffic with PASV/EPSV modes.
10+
11+
The easiest way to reproduce this issue is with PASV mode.
12+
Topoloy:
13+
```
14+
+-------------------+ +----------------------------------+
15+
| FTP: 192.168.13.2 | <-> | NAT: 192.168.13.3, 192.168.100.1 |
16+
+-------------------+ +----------------------------------+
17+
|
18+
+-----------------------+
19+
| Client: 192.168.100.2 |
20+
+-----------------------+
21+
```
22+
23+
nft ruleset:
24+
```
25+
table inet ftp_nat {
26+
ct helper ftp_helper {
27+
type "ftp" protocol tcp
28+
l3proto inet
29+
}
30+
31+
chain prerouting {
32+
type filter hook prerouting priority filter; policy
33+
accept;
34+
tcp dport 21 ct state new ct helper set "ftp_helper"
35+
}
36+
}
37+
table ip nat {
38+
chain prerouting {
39+
type nat hook prerouting priority dstnat; policy accept;
40+
tcp dport 21 dnat ip prefix to ip daddr map {
41+
192.168.100.1 : 192.168.13.2/32 }
42+
}
43+
44+
chain postrouting {
45+
type nat hook postrouting priority srcnat; policy
46+
accept;
47+
tcp sport 21 snat ip prefix to ip saddr map {
48+
192.168.13.2 : 192.168.100.1/32 }
49+
}
50+
}
51+
52+
```
53+
54+
Connecting the client:
55+
```
56+
Connected to 192.168.100.1.
57+
220 Welcome to my FTP server.
58+
Name (192.168.100.1:dev): user
59+
331 Username ok, send password.
60+
Password:
61+
230 Login successful.
62+
Remote system type is UNIX.
63+
Using binary mode to transfer files.
64+
ftp> epsv
65+
EPSV/EPRT on IPv4 off.
66+
EPSV/EPRT on IPv6 off.
67+
ftp> ls
68+
227 Entering passive mode (192,168,100,1,209,129).
69+
421 Service not available, remote server has closed connection.
70+
```
71+
72+
Kernel logs:
73+
```
74+
Oct 16 10:24:44 vyos kernel: Missing nfct_seqadj_ext_add() setup call
75+
Oct 16 10:24:44 vyos kernel: WARNING: CPU: 1 PID: 0 at
76+
net/netfilter/nf_conntrack_seqadj.c:41 nf_ct_seqadj_set+0xbf/0xe0
77+
[nf_conntrack]
78+
Oct 16 10:24:44 vyos kernel: Modules linked in: nf_nat_ftp(E) nft_nat(E)
79+
nf_conntrack_ftp(E) af_packet(E) nft_ct(E) nft_chain_nat(E) nf_nat(E)
80+
nf_tables(E) nfnetlink_cthelper(E) nf_conntrack(E) nf_defrag_ipv6(E)
81+
nf_defrag_ipv4(E) nfnetlink(E) binfmt_misc(E) intel_rapl_common(E)
82+
crct10dif_pclmul(E) crc32_pclmul(E) ghash_clmulni_intel(E)
83+
sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E)
84+
crypto_simd(E) cryptd(E) rapl(E) iTCO_wdt(E) iTCO_vendor_support(E)
85+
button(E) virtio_console(E) virtio_balloon(E) pcspkr(E) evdev(E)
86+
tcp_bbr(E) sch_fq_codel(E) mpls_iptunnel(E) mpls_router(E) ip_tunnel(E)
87+
br_netfilter(E) bridge(E) stp(E) llc(E) fuse(E) efi_pstore(E)
88+
configfs(E) virtio_rng(E) rng_core(E) ip_tables(E) x_tables(E)
89+
autofs4(E) usb_storage(E) ohci_hcd(E) uhci_hcd(E) ehci_hcd(E) sd_mod(E)
90+
squashfs(E) lz4_decompress(E) loop(E) overlay(E) ext4(E) crc16(E)
91+
mbcache(E) jbd2(E) nls_cp437(E) vfat(E) fat(E) efivarfs(E) nls_ascii(E)
92+
hid_generic(E) usbhid(E) hid(E) virtio_net(E) net_failover(E)
93+
virtio_blk(E) failover(E) ahci(E) libahci(E)
94+
Oct 16 10:24:44 vyos kernel: crc32c_intel(E) i2c_i801(E) i2c_smbus(E)
95+
libata(E) lpc_ich(E) scsi_mod(E) scsi_common(E) xhci_pci(E) xhci_hcd(E)
96+
virtio_pci(E) virtio_pci_legacy_dev(E) virtio_pci_modern_dev(E)
97+
virtio(E) virtio_ring(E)
98+
Oct 16 10:24:44 vyos kernel: CPU: 1 PID: 0 Comm: swapper/1 Tainted: G
99+
E 6.6.108-vyos #1
100+
Oct 16 10:24:44 vyos kernel: Hardware name: QEMU Standard PC (Q35 +
101+
ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
102+
Oct 16 10:24:44 vyos kernel: RIP: 0010:nf_ct_seqadj_set+0xbf/0xe0
103+
[nf_conntrack]
104+
Oct 16 10:24:44 vyos kernel: Code: ea 44 89 20 89 50 08 eb db 45 85 ed
105+
74 de 80 3d 51 6d 00 00 00 75 d5 48 c7 c7 68 57 ad c0 c6 05 41 6d 00 00
106+
01 e8 71 28 dd dc <0f> 0b eb be be 02 00 00 00 e8 63 fc ff ff 48 89 c3
107+
e9 66 ff ff ff
108+
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c00e8910 EFLAGS: 00010286
109+
Oct 16 10:24:44 vyos kernel: RAX: 0000000000000000 RBX: 0000000000000014
110+
RCX: 000000000000083f
111+
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 00000000000000f6
112+
RDI: 000000000000083f
113+
Oct 16 10:24:44 vyos kernel: RBP: ffff89387978fb00 R08: 0000000000000000
114+
R09: ffff9a66c00e87a8
115+
Oct 16 10:24:44 vyos kernel: R10: 0000000000000003 R11: ffffffff9ecbab08
116+
R12: ffff89387978fb00
117+
Oct 16 10:24:44 vyos kernel: R13: 0000000000000001 R14: ffff893872e18862
118+
R15: ffff893842f8c700
119+
Oct 16 10:24:44 vyos kernel: FS: 0000000000000000(0000)
120+
GS:ffff893bafc80000(0000) knlGS:0000000000000000
121+
Oct 16 10:24:44 vyos kernel: CS: 0010 DS: 0000 ES: 0000 CR0:
122+
0000000080050033
123+
Oct 16 10:24:44 vyos kernel: CR2: 000055fbc64ec690 CR3: 000000011de22001
124+
CR4: 0000000000370ee0
125+
Oct 16 10:24:44 vyos kernel: Call Trace:
126+
Oct 16 10:24:44 vyos kernel: <IRQ>
127+
Oct 16 10:24:44 vyos kernel: __nf_nat_mangle_tcp_packet+0x100/0x160
128+
[nf_nat]
129+
Oct 16 10:24:44 vyos kernel: nf_nat_ftp+0x142/0x280 [nf_nat_ftp]
130+
Oct 16 10:24:44 vyos kernel: ? kmem_cache_alloc+0x157/0x290
131+
Oct 16 10:24:44 vyos kernel: ? help+0x4d1/0x880 [nf_conntrack_ftp]
132+
Oct 16 10:24:44 vyos kernel: help+0x4d1/0x880 [nf_conntrack_ftp]
133+
Oct 16 10:24:44 vyos kernel: ? nf_confirm+0x122/0x2e0 [nf_conntrack]
134+
Oct 16 10:24:44 vyos kernel: nf_confirm+0x122/0x2e0 [nf_conntrack]
135+
Oct 16 10:24:44 vyos kernel: nf_hook_slow+0x3c/0xb0
136+
Oct 16 10:24:44 vyos kernel: ip_output+0xb6/0xf0
137+
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_finish_output+0x10/0x10
138+
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv_finish+0x90/0xa0
139+
Oct 16 10:24:44 vyos kernel: ip_sublist_rcv+0x190/0x220
140+
Oct 16 10:24:44 vyos kernel: ? __pfx_ip_rcv_finish+0x10/0x10
141+
Oct 16 10:24:44 vyos kernel: ip_list_rcv+0x134/0x160
142+
Oct 16 10:24:44 vyos kernel: __netif_receive_skb_list_core+0x299/0x2c0
143+
Oct 16 10:24:44 vyos kernel:
144+
netif_receive_skb_list_internal+0x1a7/0x2d0
145+
Oct 16 10:24:44 vyos kernel: napi_complete_done+0x69/0x1a0
146+
Oct 16 10:24:44 vyos kernel: virtnet_poll+0x3c0/0x540 [virtio_net]
147+
Oct 16 10:24:44 vyos kernel: __napi_poll+0x26/0x1a0
148+
Oct 16 10:24:44 vyos kernel: net_rx_action+0x141/0x2c0
149+
Oct 16 10:24:44 vyos kernel: ? lock_timer_base+0x5c/0x80
150+
Oct 16 10:24:44 vyos kernel: handle_softirqs+0xd5/0x280
151+
Oct 16 10:24:44 vyos kernel: __irq_exit_rcu+0x95/0xb0
152+
Oct 16 10:24:44 vyos kernel: common_interrupt+0x7a/0xa0
153+
Oct 16 10:24:44 vyos kernel: </IRQ>
154+
Oct 16 10:24:44 vyos kernel: <TASK>
155+
Oct 16 10:24:44 vyos kernel: asm_common_interrupt+0x22/0x40
156+
Oct 16 10:24:44 vyos kernel: RIP: 0010:pv_native_safe_halt+0xb/0x10
157+
Oct 16 10:24:44 vyos kernel: Code: 0b 66 66 2e 0f 1f 84 00 00 00 00 00
158+
0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 90 0f 00 2d
159+
29 9a 3e 00 fb f4 <c3> cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90
160+
90 90 90 90 8b
161+
Oct 16 10:24:44 vyos kernel: RSP: 0018:ffff9a66c009bed8 EFLAGS: 00000252
162+
Oct 16 10:24:44 vyos kernel: RAX: ffff893bafcaaca8 RBX: 0000000000000001
163+
RCX: 0000000000000001
164+
Oct 16 10:24:44 vyos kernel: RDX: 0000000000000000 RSI: 0000000000000083
165+
RDI: 0000000000064cec
166+
Oct 16 10:24:44 vyos kernel: RBP: ffff8938401f2200 R08: 0000000000000001
167+
R09: 0000000000000000
168+
Oct 16 10:24:44 vyos kernel: R10: 000000000001ffc0 R11: 0000000000000000
169+
R12: 0000000000000000
170+
Oct 16 10:24:44 vyos kernel: R13: 0000000000000000 R14: ffff8938401f2200
171+
R15: 0000000000000000
172+
Oct 16 10:24:44 vyos kernel: default_idle+0x5/0x20
173+
Oct 16 10:24:44 vyos kernel: default_idle_call+0x28/0xb0
174+
Oct 16 10:24:44 vyos kernel: do_idle+0x1ec/0x230
175+
Oct 16 10:24:44 vyos kernel: cpu_startup_entry+0x21/0x30
176+
Oct 16 10:24:44 vyos kernel: start_secondary+0x11a/0x140
177+
Oct 16 10:24:44 vyos kernel: secondary_startup_64_no_verify+0x178/0x17b
178+
Oct 16 10:24:44 vyos kernel: </TASK>
179+
```
180+
181+
Fixes: 1a64edf54f55 ("netfilter: nft_ct: add helper set support")
182+
Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
183+
---
184+
net/netfilter/nft_ct.c | 5 +++++
185+
1 file changed, 5 insertions(+)
186+
187+
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
188+
index d526e69a2..f358cdc5e 100644
189+
--- a/net/netfilter/nft_ct.c
190+
+++ b/net/netfilter/nft_ct.c
191+
@@ -22,6 +22,7 @@
192+
#include <net/netfilter/nf_conntrack_timeout.h>
193+
#include <net/netfilter/nf_conntrack_l4proto.h>
194+
#include <net/netfilter/nf_conntrack_expect.h>
195+
+#include <net/netfilter/nf_conntrack_seqadj.h>
196+
197+
struct nft_ct_helper_obj {
198+
struct nf_conntrack_helper *helper4;
199+
@@ -1173,6 +1174,10 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
200+
if (help) {
201+
rcu_assign_pointer(help->helper, to_assign);
202+
set_bit(IPS_HELPER_BIT, &ct->status);
203+
+
204+
+ if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
205+
+ if (!nfct_seqadj_ext_add(ct))
206+
+ regs->verdict.code = NF_DROP;
207+
}
208+
}
209+
210+
--
211+
2.43.0
212+

0 commit comments

Comments
 (0)