All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/3] netfilter: nat: snat created in route process just apply to routed traffic
@ 2016-07-30 21:54 fxp2001640163
  2016-07-31 19:00 ` Florian Westphal
  0 siblings, 1 reply; 2+ messages in thread
From: fxp2001640163 @ 2016-07-30 21:54 UTC (permalink / raw)
  To: pablo, kaber, kadlec, netfilter-devel, coreteam, netdev; +Cc: Xiaoping Fan

From: Xiaoping Fan <xfan@codeaurora.org>

In some situations, packet goes through Linux twice, one for bridging,
another for routing. If snat is created in bridging process, that means
snat rule only matches bridged traffic. If snat is created in routing
process, that means snat rule only matches routed traffic. If we apply
snat to both bridged and routed traffic, traffic will be translated
unexpectedly. So we limit snat created in bridge process to bridged
traffic, snat created in route process to routed traffic.

Signed-off-by: Xiaoping Fan <xfan@codeaurora.org>
---
 include/net/netfilter/nf_nat.h           |  9 +++++++++
 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 15 ++++++++++++++-
 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 15 ++++++++++++++-
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index c327a43..ef6e06c 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -18,12 +18,21 @@ enum nf_nat_manip_type {
 #include <linux/netfilter/nf_conntrack_pptp.h>
 #include <net/netfilter/nf_conntrack_extend.h>
 
+/* Check if packet is a bridged packet when do SNAT */
+#if defined(CONFIG_BRIDGE_NETFILTER)
+#define nf_nat_is_bridged_pkt(SKB) ((SKB)->nf_bridge && \
+				    ((SKB)->nf_bridge->physoutdev != NULL))
+#else
+#define nf_nat_is_bridged_pkt(SKB) 0
+#endif
+
 /* per conntrack: nat application helper private data */
 union nf_conntrack_nat_help {
 	/* insert nat helper private data here */
 #if defined(CONFIG_NF_NAT_PPTP) || defined(CONFIG_NF_NAT_PPTP_MODULE)
 	struct nf_nat_pptp nat_pptp_info;
 #endif
+	bool snat_in_bridge;
 };
 
 struct nf_conn;
diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
index f8aad03..41c7992 100644
--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
@@ -14,6 +14,7 @@
 #include <linux/ip.h>
 #include <linux/icmp.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv4.h>
 #include <net/secure_seq.h>
 #include <net/checksum.h>
@@ -277,6 +278,12 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
 	if (nat == NULL)
 		return NF_ACCEPT;
 
+	if ((maniptype == NF_NAT_MANIP_SRC) &&
+	    nf_nat_initialized(ct, maniptype) &&
+	    (nat->help.snat_in_bridge != nf_nat_is_bridged_pkt(skb))) {
+		return NF_ACCEPT;
+	}
+
 	switch (ctinfo) {
 	case IP_CT_RELATED:
 	case IP_CT_RELATED_REPLY:
@@ -299,8 +306,14 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
 			if (ret != NF_ACCEPT)
 				return ret;
 
-			if (nf_nat_initialized(ct, HOOK2MANIP(state->hook)))
+			if (nf_nat_initialized(ct, HOOK2MANIP(state->hook))) {
+				if (maniptype == NF_NAT_MANIP_SRC) {
+					nfct_nat(ct)->help.snat_in_bridge =
+						nf_nat_is_bridged_pkt(skb);
+				}
+
 				break;
+			}
 
 			ret = nf_nat_alloc_null_binding(ct, state->hook);
 			if (ret != NF_ACCEPT)
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index e0be97e..dc8df3a 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -12,6 +12,7 @@
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv6.h>
 #include <net/secure_seq.h>
 #include <net/checksum.h>
@@ -281,6 +282,12 @@ nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,
 	if (nat == NULL)
 		return NF_ACCEPT;
 
+	if ((maniptype == NF_NAT_MANIP_SRC) &&
+	    nf_nat_initialized(ct, maniptype) &&
+	    (nat->help.snat_in_bridge != nf_nat_is_bridged_pkt(skb))) {
+		return NF_ACCEPT;
+	}
+
 	switch (ctinfo) {
 	case IP_CT_RELATED:
 	case IP_CT_RELATED_REPLY:
@@ -308,8 +315,14 @@ nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,
 			if (ret != NF_ACCEPT)
 				return ret;
 
-			if (nf_nat_initialized(ct, HOOK2MANIP(state->hook)))
+			if (nf_nat_initialized(ct, HOOK2MANIP(state->hook))) {
+				if (maniptype == NF_NAT_MANIP_SRC) {
+					nfct_nat(ct)->help.snat_in_bridge =
+						nf_nat_is_bridged_pkt(skb);
+				}
+
 				break;
+			}
 
 			ret = nf_nat_alloc_null_binding(ct, state->hook);
 			if (ret != NF_ACCEPT)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 2/3] netfilter: nat: snat created in route process just apply to routed traffic
  2016-07-30 21:54 [PATCH 2/3] netfilter: nat: snat created in route process just apply to routed traffic fxp2001640163
@ 2016-07-31 19:00 ` Florian Westphal
  0 siblings, 0 replies; 2+ messages in thread
From: Florian Westphal @ 2016-07-31 19:00 UTC (permalink / raw)
  To: fxp2001640163
  Cc: pablo, kaber, kadlec, netfilter-devel, coreteam, netdev, Xiaoping Fan

fxp2001640163@gmail.com <fxp2001640163@gmail.com> wrote:
> From: Xiaoping Fan <xfan@codeaurora.org>
> 
> In some situations, packet goes through Linux twice, one for bridging,
> another for routing. If snat is created in bridging process, that means

Hmm, but SNAT happens in POSTROUTING.

Where can we enter routing path after bridge went though postrouting...?

Normally if bridge packet has local dst mac kb traversal is:

bridge prerouting -> bridge input -> ipv4 prerouting (hook invocation
suppressed via bridge netfilter sabotage hook)

Depending on route table we then end up in ipv4 input (again suppressed)
or in forward and postrouting.

What is the issue, exactly?

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-07-31 19:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-30 21:54 [PATCH 2/3] netfilter: nat: snat created in route process just apply to routed traffic fxp2001640163
2016-07-31 19:00 ` Florian Westphal

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.