diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2009-11-06 03:43:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-06 03:43:42 -0500 |
commit | f9dd09c7f7199685601d75882447a6598be8a3e0 (patch) | |
tree | 98ab4a75ec6c74cdb4aa807c491002ba33de56c5 /include/net | |
parent | f5209b4446d185cc95f46363f8043a743530c15a (diff) |
netfilter: nf_nat: fix NAT issue in 2.6.30.4+
Vitezslav Samel discovered that since 2.6.30.4+ active FTP can not work
over NAT. The "cause" of the problem was a fix of unacknowledged data
detection with NAT (commit a3a9f79e361e864f0e9d75ebe2a0cb43d17c4272).
However, actually, that fix uncovered a long standing bug in TCP conntrack:
when NAT was enabled, we simply updated the max of the right edge of
the segments we have seen (td_end), by the offset NAT produced with
changing IP/port in the data. However, we did not update the other parameter
(td_maxend) which is affected by the NAT offset. Thus that could drift
away from the correct value and thus resulted breaking active FTP.
The patch below fixes the issue by *not* updating the conntrack parameters
from NAT, but instead taking into account the NAT offsets in conntrack in a
consistent way. (Updating from NAT would be more harder and expensive because
it'd need to re-calculate parameters we already calculated in conntrack.)
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/netfilter/nf_conntrack.h | 8 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_helper.h | 4 |
2 files changed, 7 insertions, 5 deletions
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index cbdd6284996..5cf7270e3ff 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
@@ -255,11 +255,9 @@ static inline bool nf_ct_kill(struct nf_conn *ct) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* These are for NAT. Icky. */ | 257 | /* These are for NAT. Icky. */ |
258 | /* Update TCP window tracking data when NAT mangles the packet */ | 258 | extern s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, |
259 | extern void nf_conntrack_tcp_update(const struct sk_buff *skb, | 259 | enum ip_conntrack_dir dir, |
260 | unsigned int dataoff, | 260 | u32 seq); |
261 | struct nf_conn *ct, int dir, | ||
262 | s16 offset); | ||
263 | 261 | ||
264 | /* Fake conntrack entry for untracked connections */ | 262 | /* Fake conntrack entry for untracked connections */ |
265 | extern struct nf_conn nf_conntrack_untracked; | 263 | extern struct nf_conn nf_conntrack_untracked; |
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h index 237a961f40e..4222220920a 100644 --- a/include/net/netfilter/nf_nat_helper.h +++ b/include/net/netfilter/nf_nat_helper.h | |||
@@ -32,4 +32,8 @@ extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, | |||
32 | * to port ct->master->saved_proto. */ | 32 | * to port ct->master->saved_proto. */ |
33 | extern void nf_nat_follow_master(struct nf_conn *ct, | 33 | extern void nf_nat_follow_master(struct nf_conn *ct, |
34 | struct nf_conntrack_expect *this); | 34 | struct nf_conntrack_expect *this); |
35 | |||
36 | extern s16 nf_nat_get_offset(const struct nf_conn *ct, | ||
37 | enum ip_conntrack_dir dir, | ||
38 | u32 seq); | ||
35 | #endif | 39 | #endif |