netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Handle routing changes for the MASQUERADE target
@ 2012-11-30 20:51 Jozsef Kadlecsik
  2012-11-30 21:11 ` Florian Westphal
  2012-11-30 22:37 ` [PATCH] Handle routing changes in MASQUERADE target, v4 Jozsef Kadlecsik
  0 siblings, 2 replies; 7+ messages in thread
From: Jozsef Kadlecsik @ 2012-11-30 20:51 UTC (permalink / raw)
  To: netfilter-devel

When the route changes (backup default route, VPNs) which affect a
masqueraded target, the packets were sent out with the outdated source
address. The patch addresses the issue by comparing the outgoing interface
directly with the masqueraded interface in the nat table.

Events are inefficient in this case, because it'd require adding route
events to the network core and then scanning the whole conntrack table
and re-checking the route for all entry.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
 include/net/netfilter/nf_nat.h    |   18 ++++++++++++++++++
 net/ipv4/netfilter/iptable_nat.c  |    4 ++++
 net/ipv6/netfilter/ip6table_nat.c |    4 ++++
 3 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index bd8eea7..fc8f1b8 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -68,4 +68,22 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
 #endif
 }
 
+static inline bool nf_nat_oif_changed(const struct sk_buff *skb,
+				      unsigned int hooknum,
+				      struct nf_conn *ct,
+				      enum ip_conntrack_info ctinfo,
+				      struct nf_conn_nat *nat,
+				      const struct net_device *out)
+{
+	if (nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
+	    CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
+	    nat->masq_index != out->ifindex) {
+		/* Outgoing interface changed, destroy conntrack. */
+		nf_ct_kill_acct(cf, ctinfo, skb);
+		nf_ct_put(ct);
+		return true;
+	}
+	return false;
+}
+
 #endif
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index ac635a7..4ed34ab 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -134,6 +134,10 @@ nf_nat_ipv4_fn(unsigned int hooknum,
 		/* ESTABLISHED */
 		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
 			     ctinfo == IP_CT_ESTABLISHED_REPLY);
+#if IS_ENABLED(CONFIG_IP_NF_TARGET_MASQUERADE)
+		if (nf_nat_oif_changed(skb, hooknum, ct, ctinfo, nat, out))
+			return NF_DROP;
+#endif
 	}
 
 	return nf_nat_packet(ct, ctinfo, hooknum, skb);
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index fa84cf8..b0036a7 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -137,6 +137,10 @@ nf_nat_ipv6_fn(unsigned int hooknum,
 		/* ESTABLISHED */
 		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
 			     ctinfo == IP_CT_ESTABLISHED_REPLY);
+#if IS_ENABLED(CONFIG_IP6_NF_TARGET_MASQUERADE)
+		if (nf_nat_oif_changed(skb, hooknum, ct, ctinfo, nat, out))
+			return NF_DROP;
+#endif
 	}
 
 	return nf_nat_packet(ct, ctinfo, hooknum, skb);
-- 
1.7.0.4

-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH] Handle routing changes for the MASQUERADE target
  2012-11-30 20:51 [PATCH] Handle routing changes for the MASQUERADE target Jozsef Kadlecsik
@ 2012-11-30 21:11 ` Florian Westphal
  2012-11-30 21:27   ` Jozsef Kadlecsik
  2012-11-30 22:37 ` [PATCH] Handle routing changes in MASQUERADE target, v4 Jozsef Kadlecsik
  1 sibling, 1 reply; 7+ messages in thread
From: Florian Westphal @ 2012-11-30 21:11 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: netfilter-devel

Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> wrote:

Hi Jozsef,

> index bd8eea7..fc8f1b8 100644
> --- a/include/net/netfilter/nf_nat.h
> +++ b/include/net/netfilter/nf_nat.h
> @@ -68,4 +68,22 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
>  
> +static inline bool nf_nat_oif_changed(const struct sk_buff *skb,
> +				      unsigned int hooknum,
[..]
> +{

If you put the #if IS_ENABLED here, it would no longer be necessary
in the .c files.  nf_nat_oif_changed() would always return false
in the 'no MASQERADE' case.

> +	if (nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
> +	    CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
> +	    nat->masq_index != out->ifindex) {
> +		/* Outgoing interface changed, destroy conntrack. */
> +		nf_ct_kill_acct(cf, ctinfo, skb);
> +		nf_ct_put(ct);

Hmm. Is the nf_ct_put() correct?
nf_ct_kill invokes death_by_timeout(), which also puts ct.

> diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
> index ac635a7..4ed34ab 100644
> --- a/net/ipv4/netfilter/iptable_nat.c
> +++ b/net/ipv4/netfilter/iptable_nat.c
> @@ -134,6 +134,10 @@ nf_nat_ipv4_fn(unsigned int hooknum,
>  		/* ESTABLISHED */
>  		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
>  			     ctinfo == IP_CT_ESTABLISHED_REPLY);
> +#if IS_ENABLED(CONFIG_IP_NF_TARGET_MASQUERADE)
> +		if (nf_nat_oif_changed(skb, hooknum, ct, ctinfo, nat, out))
> +			return NF_DROP;
> +#endif
>  	}

I wonder if this:

	if (nf_nat_oif_changed(skb, hooknum, ctinfo, nat, out)) {
		nf_ct_kill_acct(ct, ctinfo, skb);
		return NF_DROP;
	}

Would be clearer (the name 'nf_nat_oif_changed' sounds like it only
performs a test).

Cheers,
Florian

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

* Re: [PATCH] Handle routing changes for the MASQUERADE target
  2012-11-30 21:11 ` Florian Westphal
@ 2012-11-30 21:27   ` Jozsef Kadlecsik
  2012-11-30 21:40     ` Florian Westphal
  0 siblings, 1 reply; 7+ messages in thread
From: Jozsef Kadlecsik @ 2012-11-30 21:27 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

Hi Florian,

On Fri, 30 Nov 2012, Florian Westphal wrote:

> Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> wrote:
> 
> > index bd8eea7..fc8f1b8 100644
> > --- a/include/net/netfilter/nf_nat.h
> > +++ b/include/net/netfilter/nf_nat.h
> > @@ -68,4 +68,22 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
> >  
> > +static inline bool nf_nat_oif_changed(const struct sk_buff *skb,
> > +				      unsigned int hooknum,
> [..]
> > +{
> 
> If you put the #if IS_ENABLED here, it would no longer be necessary
> in the .c files.  nf_nat_oif_changed() would always return false
> in the 'no MASQERADE' case.

Yes, you're right - and a few lines are spared again :-).
 
> > +	if (nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
> > +	    CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
> > +	    nat->masq_index != out->ifindex) {
> > +		/* Outgoing interface changed, destroy conntrack. */
> > +		nf_ct_kill_acct(cf, ctinfo, skb);
> > +		nf_ct_put(ct);
> 
> Hmm. Is the nf_ct_put() correct?
> nf_ct_kill invokes death_by_timeout(), which also puts ct.

nf_nat_ipv[46]_fn starts with "nf_ct_get", so that must be released. 
Technically the last nf_ct_put destroys the entry.
 
> > diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
> > index ac635a7..4ed34ab 100644
> > --- a/net/ipv4/netfilter/iptable_nat.c
> > +++ b/net/ipv4/netfilter/iptable_nat.c
> > @@ -134,6 +134,10 @@ nf_nat_ipv4_fn(unsigned int hooknum,
> >  		/* ESTABLISHED */
> >  		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
> >  			     ctinfo == IP_CT_ESTABLISHED_REPLY);
> > +#if IS_ENABLED(CONFIG_IP_NF_TARGET_MASQUERADE)
> > +		if (nf_nat_oif_changed(skb, hooknum, ct, ctinfo, nat, out))
> > +			return NF_DROP;
> > +#endif
> >  	}
> 
> I wonder if this:
> 
> 	if (nf_nat_oif_changed(skb, hooknum, ctinfo, nat, out)) {
> 		nf_ct_kill_acct(ct, ctinfo, skb);
> 		return NF_DROP;
> 	}
> 
> Would be clearer (the name 'nf_nat_oif_changed' sounds like it only
> performs a test).

OK, I'll send an updated version.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH] Handle routing changes for the MASQUERADE target
  2012-11-30 21:27   ` Jozsef Kadlecsik
@ 2012-11-30 21:40     ` Florian Westphal
  2012-11-30 22:28       ` Jozsef Kadlecsik
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Westphal @ 2012-11-30 21:40 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Florian Westphal, netfilter-devel

Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> wrote:
> > > +	if (nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
> > > +	    CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
> > > +	    nat->masq_index != out->ifindex) {
> > > +		/* Outgoing interface changed, destroy conntrack. */
> > > +		nf_ct_kill_acct(cf, ctinfo, skb);
> > > +		nf_ct_put(ct);
> > 
> > Hmm. Is the nf_ct_put() correct?
> > nf_ct_kill invokes death_by_timeout(), which also puts ct.
> 
> nf_nat_ipv[46]_fn starts with "nf_ct_get", so that must be released. 

nf_ct_get() does not increase refcount :)

Regards,
Florian

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

* Re: [PATCH] Handle routing changes for the MASQUERADE target
  2012-11-30 21:40     ` Florian Westphal
@ 2012-11-30 22:28       ` Jozsef Kadlecsik
  0 siblings, 0 replies; 7+ messages in thread
From: Jozsef Kadlecsik @ 2012-11-30 22:28 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, 30 Nov 2012, Florian Westphal wrote:

> Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> wrote:
> > > > +	if (nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
> > > > +	    CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
> > > > +	    nat->masq_index != out->ifindex) {
> > > > +		/* Outgoing interface changed, destroy conntrack. */
> > > > +		nf_ct_kill_acct(cf, ctinfo, skb);
> > > > +		nf_ct_put(ct);
> > > 
> > > Hmm. Is the nf_ct_put() correct?
> > > nf_ct_kill invokes death_by_timeout(), which also puts ct.
> > 
> > nf_nat_ipv[46]_fn starts with "nf_ct_get", so that must be released. 
> 
> nf_ct_get() does not increase refcount :)

Ohh, right - I'm blind.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

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

* [PATCH] Handle routing changes in MASQUERADE target, v4
  2012-11-30 20:51 [PATCH] Handle routing changes for the MASQUERADE target Jozsef Kadlecsik
  2012-11-30 21:11 ` Florian Westphal
@ 2012-11-30 22:37 ` Jozsef Kadlecsik
  2012-12-03 18:28   ` Pablo Neira Ayuso
  1 sibling, 1 reply; 7+ messages in thread
From: Jozsef Kadlecsik @ 2012-11-30 22:37 UTC (permalink / raw)
  To: netfilter-devel

When the route changes (backup default route, VPNs) which affect a
masqueraded target, the packets were sent out with the outdated source
address. The patch addresses the issue by comparing the outgoing interface
directly with the masqueraded interface in the nat table.

Events are inefficient in this case, because it'd require adding route
events to the network core and then scanning the whole conntrack table
and re-checking the route for all entry.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
 include/net/netfilter/nf_nat.h    |   15 +++++++++++++++
 net/ipv4/netfilter/iptable_nat.c  |    4 ++++
 net/ipv6/netfilter/ip6table_nat.c |    4 ++++
 3 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index bd8eea7..ad14a79 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -68,4 +68,19 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
 #endif
 }
 
+static inline bool nf_nat_oif_changed(unsigned int hooknum,
+				      enum ip_conntrack_info ctinfo,
+				      struct nf_conn_nat *nat,
+				      const struct net_device *out)
+{
+#if IS_ENABLED(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+    IS_ENABLED(CONFIG_IP6_NF_TARGET_MASQUERADE)
+	return nat->masq_index && hooknum == NF_INET_POST_ROUTING &&
+	       CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL &&
+	       nat->masq_index != out->ifindex;
+#else
+	return false;
+#endif
+}
+
 #endif
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index ac635a7..da2c8a3 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -134,6 +134,10 @@ nf_nat_ipv4_fn(unsigned int hooknum,
 		/* ESTABLISHED */
 		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
 			     ctinfo == IP_CT_ESTABLISHED_REPLY);
+		if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) {
+			nf_ct_kill_acct(ct, ctinfo, skb);
+			return NF_DROP;
+		}
 	}
 
 	return nf_nat_packet(ct, ctinfo, hooknum, skb);
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index fa84cf8..6c8ae24 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -137,6 +137,10 @@ nf_nat_ipv6_fn(unsigned int hooknum,
 		/* ESTABLISHED */
 		NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
 			     ctinfo == IP_CT_ESTABLISHED_REPLY);
+		if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) {
+			nf_ct_kill_acct(ct, ctinfo, skb);
+			return NF_DROP;
+		}
 	}
 
 	return nf_nat_packet(ct, ctinfo, hooknum, skb);
-- 
1.7.0.4


Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH] Handle routing changes in MASQUERADE target, v4
  2012-11-30 22:37 ` [PATCH] Handle routing changes in MASQUERADE target, v4 Jozsef Kadlecsik
@ 2012-12-03 18:28   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2012-12-03 18:28 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: netfilter-devel

On Fri, Nov 30, 2012 at 11:37:26PM +0100, Jozsef Kadlecsik wrote:
> When the route changes (backup default route, VPNs) which affect a
> masqueraded target, the packets were sent out with the outdated source
> address. The patch addresses the issue by comparing the outgoing interface
> directly with the masqueraded interface in the nat table.
> 
> Events are inefficient in this case, because it'd require adding route
> events to the network core and then scanning the whole conntrack table
> and re-checking the route for all entry.

Applied, thanks.

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

end of thread, other threads:[~2012-12-03 18:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-30 20:51 [PATCH] Handle routing changes for the MASQUERADE target Jozsef Kadlecsik
2012-11-30 21:11 ` Florian Westphal
2012-11-30 21:27   ` Jozsef Kadlecsik
2012-11-30 21:40     ` Florian Westphal
2012-11-30 22:28       ` Jozsef Kadlecsik
2012-11-30 22:37 ` [PATCH] Handle routing changes in MASQUERADE target, v4 Jozsef Kadlecsik
2012-12-03 18:28   ` Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).