All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: "David S. Miller" <davem@davemloft.net>
Cc: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
Subject: [NETFILTER]: Fix NAT sequence number adjustment
Date: Fri, 22 Apr 2005 00:55:48 +0200	[thread overview]
Message-ID: <42682F74.9030203@trash.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 207 bytes --]

Hi Dave,

another important fix which should go in 2.6.12 if possible.
NAT sequence number adjustment is broken since 2.6.11, quite
a few people have reported failing and corrupted FTP control
connections.


[-- Attachment #2: x --]
[-- Type: text/plain, Size: 12572 bytes --]

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/04/22 00:52:27+02:00 kaber@coreworks.de 
#   [NETFILTER]: Fix NAT sequence number adjustment
#   
#   The NAT changes in 2.6.11 changed the position where helpers
#   are called and perform packet mangling. Before 2.6.11, a NAT
#   helper was called before the packet was NATed and had its
#   sequence number adjusted. Since 2.6.11, the helpers get packets
#   with already adjusted sequence numbers.
#   
#   This breaks sequence number adjustment, adjust_tcp_sequence()
#   needs the original sequence number to determine whether
#   a packet was a retransmission and to store it for further
#   corrections. It can't be reconstructed without more information
#   than available, so this patch restores the old order by
#   calling helpers from a new conntrack hook two priorities
#   below ip_conntrack_confirm() and adjusting the sequence number
#   from a new NAT hook one priority below ip_conntrack_confirm().
#   
#   Tracked down by Phil Oester <kernel@linuxace.com>
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_standalone.c
#   2005/04/22 00:52:19+02:00 kaber@coreworks.de +53 -1
#   [NETFILTER]: Fix NAT sequence number adjustment
#   
#   The NAT changes in 2.6.11 changed the position where helpers
#   are called and perform packet mangling. Before 2.6.11, a NAT
#   helper was called before the packet was NATed and had its
#   sequence number adjusted. Since 2.6.11, the helpers get packets
#   with already adjusted sequence numbers.
#   
#   This breaks sequence number adjustment, adjust_tcp_sequence()
#   needs the original sequence number to determine whether
#   a packet was a retransmission and to store it for further
#   corrections. It can't be reconstructed without more information
#   than available, so this patch restores the old order by
#   calling helpers from a new conntrack hook two priorities
#   below ip_conntrack_confirm() and adjusting the sequence number
#   from a new NAT hook one priority below ip_conntrack_confirm().
#   
#   Tracked down by Phil Oester <kernel@linuxace.com>
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_core.c
#   2005/04/22 00:52:19+02:00 kaber@coreworks.de +0 -9
#   [NETFILTER]: Fix NAT sequence number adjustment
#   
#   The NAT changes in 2.6.11 changed the position where helpers
#   are called and perform packet mangling. Before 2.6.11, a NAT
#   helper was called before the packet was NATed and had its
#   sequence number adjusted. Since 2.6.11, the helpers get packets
#   with already adjusted sequence numbers.
#   
#   This breaks sequence number adjustment, adjust_tcp_sequence()
#   needs the original sequence number to determine whether
#   a packet was a retransmission and to store it for further
#   corrections. It can't be reconstructed without more information
#   than available, so this patch restores the old order by
#   calling helpers from a new conntrack hook two priorities
#   below ip_conntrack_confirm() and adjusting the sequence number
#   from a new NAT hook one priority below ip_conntrack_confirm().
#   
#   Tracked down by Phil Oester <kernel@linuxace.com>
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_conntrack_standalone.c
#   2005/04/22 00:52:19+02:00 kaber@coreworks.de +45 -6
#   [NETFILTER]: Fix NAT sequence number adjustment
#   
#   The NAT changes in 2.6.11 changed the position where helpers
#   are called and perform packet mangling. Before 2.6.11, a NAT
#   helper was called before the packet was NATed and had its
#   sequence number adjusted. Since 2.6.11, the helpers get packets
#   with already adjusted sequence numbers.
#   
#   This breaks sequence number adjustment, adjust_tcp_sequence()
#   needs the original sequence number to determine whether
#   a packet was a retransmission and to store it for further
#   corrections. It can't be reconstructed without more information
#   than available, so this patch restores the old order by
#   calling helpers from a new conntrack hook two priorities
#   below ip_conntrack_confirm() and adjusting the sequence number
#   from a new NAT hook one priority below ip_conntrack_confirm().
#   
#   Tracked down by Phil Oester <kernel@linuxace.com>
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv4.h
#   2005/04/22 00:52:19+02:00 kaber@coreworks.de +3 -0
#   [NETFILTER]: Fix NAT sequence number adjustment
#   
#   The NAT changes in 2.6.11 changed the position where helpers
#   are called and perform packet mangling. Before 2.6.11, a NAT
#   helper was called before the packet was NATed and had its
#   sequence number adjusted. Since 2.6.11, the helpers get packets
#   with already adjusted sequence numbers.
#   
#   This breaks sequence number adjustment, adjust_tcp_sequence()
#   needs the original sequence number to determine whether
#   a packet was a retransmission and to store it for further
#   corrections. It can't be reconstructed without more information
#   than available, so this patch restores the old order by
#   calling helpers from a new conntrack hook two priorities
#   below ip_conntrack_confirm() and adjusting the sequence number
#   from a new NAT hook one priority below ip_conntrack_confirm().
#   
#   Tracked down by Phil Oester <kernel@linuxace.com>
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
diff -Nru a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
--- a/include/linux/netfilter_ipv4.h	2005-04-22 00:52:48 +02:00
+++ b/include/linux/netfilter_ipv4.h	2005-04-22 00:52:48 +02:00
@@ -62,6 +62,9 @@
 	NF_IP_PRI_FILTER = 0,
 	NF_IP_PRI_NAT_SRC = 100,
 	NF_IP_PRI_SELINUX_LAST = 225,
+	NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
+	NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
+	NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
 	NF_IP_PRI_LAST = INT_MAX,
 };
 
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-04-22 00:52:48 +02:00
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-04-22 00:52:48 +02:00
@@ -401,6 +401,16 @@
 			       const struct net_device *out,
 			       int (*okfn)(struct sk_buff *))
 {
+	/* We've seen it coming out the other side: confirm it */
+	return ip_conntrack_confirm(pskb);
+}
+
+static unsigned int ip_conntrack_help(unsigned int hooknum,
+				      struct sk_buff **pskb,
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
+{
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 
@@ -412,9 +422,7 @@
 		if (ret != NF_ACCEPT)
 			return ret;
 	}
-
-	/* We've seen it coming out the other side: confirm it */
-	return ip_conntrack_confirm(pskb);
+	return NF_ACCEPT;
 }
 
 static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -516,13 +524,30 @@
 	.priority	= NF_IP_PRI_CONNTRACK,
 };
 
+/* helpers */
+static struct nf_hook_ops ip_conntrack_helper_out_ops = {
+	.hook		= ip_conntrack_help,
+	.owner		= THIS_MODULE,
+	.pf		= PF_INET,
+	.hooknum	= NF_IP_POST_ROUTING,
+	.priority	= NF_IP_PRI_CONNTRACK_HELPER,
+};
+
+static struct nf_hook_ops ip_conntrack_helper_in_ops = {
+	.hook		= ip_conntrack_help,
+	.owner		= THIS_MODULE,
+	.pf		= PF_INET,
+	.hooknum	= NF_IP_LOCAL_IN,
+	.priority	= NF_IP_PRI_CONNTRACK_HELPER,
+};
+
 /* Refragmenter; last chance. */
 static struct nf_hook_ops ip_conntrack_out_ops = {
 	.hook		= ip_refrag,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
 	.hooknum	= NF_IP_POST_ROUTING,
-	.priority	= NF_IP_PRI_LAST,
+	.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 };
 
 static struct nf_hook_ops ip_conntrack_local_in_ops = {
@@ -530,7 +555,7 @@
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
 	.hooknum	= NF_IP_LOCAL_IN,
-	.priority	= NF_IP_PRI_LAST-1,
+	.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 };
 
 /* Sysctl support */
@@ -831,10 +856,20 @@
 		printk("ip_conntrack: can't register local out hook.\n");
 		goto cleanup_inops;
 	}
+	ret = nf_register_hook(&ip_conntrack_helper_in_ops);
+	if (ret < 0) {
+		printk("ip_conntrack: can't register local in helper hook.\n");
+		goto cleanup_inandlocalops;
+	}
+	ret = nf_register_hook(&ip_conntrack_helper_out_ops);
+	if (ret < 0) {
+		printk("ip_conntrack: can't register postrouting helper hook.\n");
+		goto cleanup_helperinops;
+	}
 	ret = nf_register_hook(&ip_conntrack_out_ops);
 	if (ret < 0) {
 		printk("ip_conntrack: can't register post-routing hook.\n");
-		goto cleanup_inandlocalops;
+		goto cleanup_helperoutops;
 	}
 	ret = nf_register_hook(&ip_conntrack_local_in_ops);
 	if (ret < 0) {
@@ -860,6 +895,10 @@
 	nf_unregister_hook(&ip_conntrack_local_in_ops);
  cleanup_inoutandlocalops:
 	nf_unregister_hook(&ip_conntrack_out_ops);
+ cleanup_helperoutops:
+	nf_unregister_hook(&ip_conntrack_helper_out_ops);
+ cleanup_helperinops:
+	nf_unregister_hook(&ip_conntrack_helper_in_ops);
  cleanup_inandlocalops:
 	nf_unregister_hook(&ip_conntrack_local_out_ops);
  cleanup_inops:
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c	2005-04-22 00:52:48 +02:00
+++ b/net/ipv4/netfilter/ip_nat_core.c	2005-04-22 00:52:48 +02:00
@@ -356,15 +356,6 @@
 	unsigned long statusbit;
 	enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
 
-	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
-	    && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
-		DEBUGP("ip_nat_core: adjusting sequence number\n");
-		/* future: put this in a l4-proto specific function,
-		 * and call this function here. */
-		if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
-			return NF_DROP;
-	}
-
 	if (mtype == IP_NAT_MANIP_SRC)
 		statusbit = IPS_SRC_NAT;
 	else
diff -Nru a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
--- a/net/ipv4/netfilter/ip_nat_standalone.c	2005-04-22 00:52:48 +02:00
+++ b/net/ipv4/netfilter/ip_nat_standalone.c	2005-04-22 00:52:48 +02:00
@@ -230,6 +230,25 @@
 	return ret;
 }
 
+static unsigned int
+ip_nat_adjust(unsigned int hooknum,
+	      struct sk_buff **pskb,
+	      const struct net_device *in,
+	      const struct net_device *out,
+	      int (*okfn)(struct sk_buff *))
+{
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+
+	ct = ip_conntrack_get(*pskb, &ctinfo);
+	if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
+	        DEBUGP("ip_nat_standalone: adjusting sequence number\n");
+	        if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
+	                return NF_DROP;
+	}
+	return NF_ACCEPT;
+}
+
 /* We must be after connection tracking and before packet filtering. */
 
 /* Before packet filtering, change destination */
@@ -250,6 +269,15 @@
 	.priority	= NF_IP_PRI_NAT_SRC,
 };
 
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_out_ops = {
+	.hook		= ip_nat_adjust,
+	.owner		= THIS_MODULE,
+	.pf		= PF_INET,
+	.hooknum	= NF_IP_POST_ROUTING,
+	.priority	= NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_local_out_ops = {
 	.hook		= ip_nat_local_fn,
@@ -268,6 +296,16 @@
 	.priority	= NF_IP_PRI_NAT_SRC,
 };
 
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_in_ops = {
+	.hook		= ip_nat_adjust,
+	.owner		= THIS_MODULE,
+	.pf		= PF_INET,
+	.hooknum	= NF_IP_LOCAL_IN,
+	.priority	= NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
+
 static int init_or_cleanup(int init)
 {
 	int ret = 0;
@@ -296,10 +334,20 @@
 		printk("ip_nat_init: can't register out hook.\n");
 		goto cleanup_inops;
 	}
+	ret = nf_register_hook(&ip_nat_adjust_in_ops);
+	if (ret < 0) {
+		printk("ip_nat_init: can't register adjust in hook.\n");
+		goto cleanup_outops;
+	}
+	ret = nf_register_hook(&ip_nat_adjust_out_ops);
+	if (ret < 0) {
+		printk("ip_nat_init: can't register adjust out hook.\n");
+		goto cleanup_adjustin_ops;
+	}
 	ret = nf_register_hook(&ip_nat_local_out_ops);
 	if (ret < 0) {
 		printk("ip_nat_init: can't register local out hook.\n");
-		goto cleanup_outops;
+		goto cleanup_adjustout_ops;;
 	}
 	ret = nf_register_hook(&ip_nat_local_in_ops);
 	if (ret < 0) {
@@ -312,6 +360,10 @@
 	nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
 	nf_unregister_hook(&ip_nat_local_out_ops);
+ cleanup_adjustout_ops:
+	nf_unregister_hook(&ip_nat_adjust_out_ops);
+ cleanup_adjustin_ops:
+	nf_unregister_hook(&ip_nat_adjust_in_ops);
  cleanup_outops:
 	nf_unregister_hook(&ip_nat_out_ops);
  cleanup_inops:

             reply	other threads:[~2005-04-21 22:55 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-21 22:55 Patrick McHardy [this message]
2005-04-25  1:42 ` [NETFILTER]: Fix NAT sequence number adjustment David S. Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42682F74.9030203@trash.net \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.