All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Kernel Netdev Mailing List <netdev@vger.kernel.org>,
	Netfilter Development Mailinglist
	<netfilter-devel@lists.netfilter.org>
Subject: [PATCH 09/10]: [NETFILTER]: Redo policy lookups after NAT when neccessary
Date: Fri, 11 Nov 2005 04:19:36 +0100	[thread overview]
Message-ID: <43740DC8.5010706@trash.net> (raw)

[-- Attachment #1: 09.diff --]
[-- Type: text/x-patch, Size: 5200 bytes --]

[NETFILTER]: Redo policy lookups after NAT when neccessary

When NAT changes the key used for the xfrm lookup on the output
path the lookup needs to be redone.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit d449eeda76508f14f27d76a84350e4069c968497
tree fa245e3599e04432ee1ef1e046eeef9c800553e3
parent 351bc1c8a9c5c5e4aa48c153f0050f0a8b979201
author Patrick McHardy <kaber@trash.net> Fri, 11 Nov 2005 03:21:13 +0100
committer Patrick McHardy <kaber@trash.net> Fri, 11 Nov 2005 03:21:13 +0100

 include/net/dst.h                      |    1 +
 include/net/ip.h                       |    1 +
 net/ipv4/ip_output.c                   |    6 ++++++
 net/ipv4/netfilter.c                   |    6 ++++--
 net/ipv4/netfilter/ip_nat_standalone.c |   27 +++++++++++++++++++++++++--
 net/ipv4/xfrm4_output.c                |    1 +
 6 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 7eadd0c..4630e17 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -237,6 +237,7 @@ static inline int dst_output(struct sk_b
 }
 
 #if defined(CONFIG_XFRM) && defined(CONFIG_NETFILTER)
+extern int __ip_dst_output(struct sk_buff *skb);
 extern int ip_dst_output(struct sk_buff *skb);
 extern int ip6_dst_output(struct sk_buff *skb);
 #else
diff --git a/include/net/ip.h b/include/net/ip.h
index 9f09882..377036b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -45,6 +45,7 @@ struct inet_skb_parm
 #define IPSKB_TRANSLATED	2
 #define IPSKB_FORWARDED		4
 #define IPSKB_XFRM_TUNNEL_SIZE	8
+#define IPSKB_XFRM_TRANSFORMED	16
 };
 
 struct ipcm_cookie
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index eb6906d..579877f 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -167,6 +167,12 @@ static inline int ip_finish_output3(stru
 	struct net_device *dev = dst->dev;
 	int hh_len = LL_RESERVED_SPACE(dev);
 
+#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
+	/* Policy lookup after SNAT yielded a new policy */
+	if (dst->xfrm != NULL)
+		return __ip_dst_output(skb);
+#endif
+
 	/* Be paranoid, rather than too clever. */
 	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
 		struct sk_buff *skb2;
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 0f6616f..8fda96a 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -13,6 +13,7 @@
 #include <linux/ip.h>
 #include <net/route.h>
 #include <net/xfrm.h>
+#include <net/ip.h>
 
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 int ip_route_me_harder(struct sk_buff **pskb)
@@ -61,7 +62,8 @@ int ip_route_me_harder(struct sk_buff **
 		return -1;
 
 #ifdef CONFIG_XFRM
-	if (xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
+	if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+	    xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
 		if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
 			return -1;
 #endif
@@ -85,7 +87,7 @@ int ip_route_me_harder(struct sk_buff **
 EXPORT_SYMBOL(ip_route_me_harder);
 
 #ifdef CONFIG_XFRM
-static inline int __ip_dst_output(struct sk_buff *skb)
+inline int __ip_dst_output(struct sk_buff *skb)
 {
 	int err;
 
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index ff24bac..e383b16 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -187,6 +187,10 @@ ip_nat_out(unsigned int hooknum,
 	   const struct net_device *out,
 	   int (*okfn)(struct sk_buff *))
 {
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+	unsigned int ret;
+
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
 	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
@@ -194,7 +198,21 @@ ip_nat_out(unsigned int hooknum,
 
 	WARN_ON((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET));
 
-	return ip_nat_fn(hooknum, pskb, in, out, okfn);
+	ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+	if (ret != NF_DROP && ret != NF_STOLEN
+	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+		if (ct->tuplehash[dir].tuple.src.ip !=
+		    ct->tuplehash[!dir].tuple.dst.ip
+#ifdef CONFIG_XFRM
+		    || ct->tuplehash[dir].tuple.src.u.all !=
+		       ct->tuplehash[!dir].tuple.dst.u.all
+#endif
+		    )
+			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+	}
+	return ret;
 }
 
 static unsigned int
@@ -219,7 +237,12 @@ ip_nat_local_fn(unsigned int hooknum,
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
 		if (ct->tuplehash[dir].tuple.dst.ip !=
-		    ct->tuplehash[!dir].tuple.src.ip)
+		    ct->tuplehash[!dir].tuple.src.ip
+#ifdef CONFIG_XFRM
+		    || ct->tuplehash[dir].tuple.dst.u.all !=
+		       ct->tuplehash[dir].tuple.src.u.all
+#endif
+		    )
 			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
 	}
 	return ret;
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c135746..9e49eeb 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -133,6 +133,7 @@ int xfrm4_output(struct sk_buff *skb)
 		err = -EHOSTUNREACH;
 		goto error_nolock;
 	}
+	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
 	nf_reset(skb);
 	err = NET_XMIT_BYPASS;
 

                 reply	other threads:[~2005-11-11  3:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=43740DC8.5010706@trash.net \
    --to=kaber@trash.net \
    --cc=netdev@vger.kernel.org \
    --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.