All of lore.kernel.org
 help / color / mirror / Atom feed
* Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
@ 2003-04-13 18:53 Leen Besselink
  2003-04-13 20:13 ` Leen Besselink
  2003-04-14  7:59 ` Patrick Schaaf
  0 siblings, 2 replies; 10+ messages in thread
From: Leen Besselink @ 2003-04-13 18:53 UTC (permalink / raw)
  To: netfilter-devel

Hi netfilter-hackers,

OK, first the situation...

I use policy routing to decide (based on the from-address) on what
out-interface to send a packet (and thus a different sender IP-address and
gateway).

But... when I use reject-with tcp-reset, for a port on a host on the
network behind my firewall, the tcp-reset-packet goes over the wrong
interface.

I looked at the code and it looks like a bug to me, but there is a
comment, maybe there is a good reason not to:

        /* Routing: if not headed for us, route won't like source */
        if (ip_route_output(&rt, nskb->nh.iph->daddr,
                            local ? nskb->nh.iph->saddr : 0,
                            RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
                            0) != 0)
                goto free_nskb;

If it's not a local destinated-packet it sends the sender-address to 0
when making the routing decision (probably 0.0.0.0 ?).

The calling code for send_reset sets local:

        case IPT_TCP_RESET:
                send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);

When I use the send_unreach (for example with: icmp_host_unreachable),
this is not done and thus the source-based routing rules have effect:

        if (ip_route_output(&rt, iph->saddr, saddr, RT_TOS(tos), 0))
                return;

So, I think the 'local ? nskb->nh.iph->saddr : 0' can actually be
removed, am I right ?

But if there is a good reason, then I don't understand why it's not doing
the same thing for an unreachable, maybe that needs fixing instead then.

Any help would be greatly appreciated and tia,
	Leen.
_____________________________________
New things are always on the horizon.

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-13 18:53 Bug (?) in ipt_reject doesn't follow policy routing (2.4.x) Leen Besselink
@ 2003-04-13 20:13 ` Leen Besselink
  2003-04-14  7:27   ` Leen Besselink
  2003-04-14  7:59 ` Patrick Schaaf
  1 sibling, 1 reply; 10+ messages in thread
From: Leen Besselink @ 2003-04-13 20:13 UTC (permalink / raw)
  To: netfilter-devel

On Sun, 13 Apr 2003, Leen Besselink wrote:

> Hi netfilter-hackers,
> 
> So, I think the 'local ? nskb->nh.iph->saddr : 0' can actually be
> removed, am I right ?
> 

OK, tried that, didn't work..., strange, maybe I should just add a printk
or something, see what happends, or see if I have a routing problem as
well.

Works with the default-route, strange. BTW, I think the part
about: RTO_CONN can be removed as well..., it supposidly old:

#define RTO_CONN        0
/* RTO_CONN is not used (being alias for 0), but preserved not to break
 * some modules referring to it. */

> But if there is a good reason, then I don't understand why it's not doing
> the same thing for an unreachable, maybe that needs fixing instead then.
> 

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-13 20:13 ` Leen Besselink
@ 2003-04-14  7:27   ` Leen Besselink
  0 siblings, 0 replies; 10+ messages in thread
From: Leen Besselink @ 2003-04-14  7:27 UTC (permalink / raw)
  To: netfilter-devel

On Sun, 13 Apr 2003, Leen Besselink wrote:

> On Sun, 13 Apr 2003, Leen Besselink wrote:
> 
> > Hi netfilter-hackers,
> > 
> > So, I think the 'local ? nskb->nh.iph->saddr : 0' can actually be
> > removed, am I right ?
> > 
> 
> OK, tried that, didn't work..., strange, maybe I should just add a printk
> or something, see what happends, or see if I have a routing problem as
> well.
> 
> Works with the default-route, strange. BTW, I think the part

OK, I took a closer look, the icmp's from --reject-with don't go past the
policy-routing rules either.

Any ideas on how I can make it so, any pointers ?

tia,
	Leen.

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-13 18:53 Bug (?) in ipt_reject doesn't follow policy routing (2.4.x) Leen Besselink
  2003-04-13 20:13 ` Leen Besselink
@ 2003-04-14  7:59 ` Patrick Schaaf
  2003-04-14  8:49   ` Patrick McHardy
  1 sibling, 1 reply; 10+ messages in thread
From: Patrick Schaaf @ 2003-04-14  7:59 UTC (permalink / raw)
  To: Leen Besselink; +Cc: netfilter-devel

HiHo,

> OK, first the situation...
> 
> I use policy routing to decide (based on the from-address) on what
> out-interface to send a packet (and thus a different sender IP-address and
> gateway).
> 
> But... when I use reject-with tcp-reset, for a port on a host on the
> network behind my firewall, the tcp-reset-packet goes over the wrong
> interface.

I don't understand that description fully. Let's be more specific.
You have an outside host O, a policy router P, and an inside target T.
Further assume that O sends in packets on P.eth0, and T sits on P.eth1.

1) when O sends a packet to P, P will see a source-NATted address Q, right?
   If not, what did you mean with 'thus a different sender IP-address'?

2) is the reject-with-tcp-reset rule on P or T?

3) in the situation you describe, O tries to send to T?

4) when the RST goes out the wrong interface, what interface is that,
   and on what interface did the packet come in?

5) how do the source and destination IP addresses of that RST packet
   look at PREROUTING?

6) how do the source and destination IP addresses of that RST packet
   look at POSTROUTING / on the outgoing wire?

Maybe, if you can answer these questions, we'll be able to understand
your problem. Maybe somebody can do that even without those answers,
but the silence you received up to now indicates that's unlikely.

best regards
  Patrick

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-14  7:59 ` Patrick Schaaf
@ 2003-04-14  8:49   ` Patrick McHardy
  2003-04-14 11:35     ` Leen Besselink
  0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-14  8:49 UTC (permalink / raw)
  To: Patrick Schaaf; +Cc: Leen Besselink, netfilter-devel

Patrick Schaaf wrote:

>Maybe, if you can answer these questions, we'll be able to understand
>your problem. Maybe somebody can do that even without those answers,
>but the silence you received up to now indicates that's unlikely.
>  
>

May I ? ;)

Without beeing specific to his setup, the problem he describes is
that ipt_REJECT (and others) always choose lsrc to be 0 if it's 
non-local for
the routing decision. I'll just make a simple example:

Routing Rules (incomplete):
1000: from 10.0.0.0/8 lookup abc
32766:  from all lookup main

Routing tables (incomplete):
abc: default via 192.168.0.1 dev eth0
main: default via 172.20.0.1 dev eth1

So all packets except those with src=10.0.0.0/8 should go through 
172.20.0.1.
When ipt_REJECT send a reject for any non-local address in 10.0.0.0/8 it 
chooses
lsrc=0 for the routing lookup, so it ends up with default route of table 
main
instead of table abc.

I wonder why ip_route_input isn't used, this should eliminate the need for
using different information from what is contained in the actual packet for
the routing lookup ..

Bye,
Patrick

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-14  8:49   ` Patrick McHardy
@ 2003-04-14 11:35     ` Leen Besselink
  2003-04-14 21:09       ` Patrick McHardy
  0 siblings, 1 reply; 10+ messages in thread
From: Leen Besselink @ 2003-04-14 11:35 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel

On Mon, 14 Apr 2003, Patrick McHardy wrote:

> Patrick Schaaf wrote:
> 
> >Maybe, if you can answer these questions, we'll be able to understand
> >your problem. Maybe somebody can do that even without those answers,
> >but the silence you received up to now indicates that's unlikely.
> >  
> >
> 
> May I ? ;)
> 

You sure can. I was going to make a long story, but you made a nice
consice explaination, thank you.

> Without beeing specific to his setup, the problem he describes is
> that ipt_REJECT (and others) always choose lsrc to be 0 if it's 
> non-local for
> the routing decision. I'll just make a simple example:
> 
> Routing Rules (incomplete):
> 1000: from 10.0.0.0/8 lookup abc
> 32766:  from all lookup main
> 
> Routing tables (incomplete):
> abc: default via 192.168.0.1 dev eth0
> main: default via 172.20.0.1 dev eth1
> 
> So all packets except those with src=10.0.0.0/8 should go through 
> 172.20.0.1.
> When ipt_REJECT send a reject for any non-local address in 10.0.0.0/8 it 
> chooses
> lsrc=0 for the routing lookup, so it ends up with default route of table 
> main
> instead of table abc.
> 
> I wonder why ip_route_input isn't used, this should eliminate the need for
> using different information from what is contained in the actual packet for
> the routing lookup ..
> 

It's a safety messure, maybe because they are afraid of loops...? And
because it touches/triggers other things, like NAT, so it seems, when I
look at the code.

You have a firewall-rule of which an incoming packet would trigger a new
packet, which might trigger a firewall-rule to trigger an other packet...
etc. But maybe I'm wrong, I'm not familair with the code (yet ?).

> Bye,
> Patrick

Thanks again.

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-14 11:35     ` Leen Besselink
@ 2003-04-14 21:09       ` Patrick McHardy
  2003-04-15  7:40         ` Harald Welte
  0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-14 21:09 UTC (permalink / raw)
  To: leen; +Cc: netfilter-devel

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

Hi Leen,

Leen Besselink wrote:

>It's a safety messure, maybe because they are afraid of loops...? And
>because it touches/triggers other things, like NAT, so it seems, when I
>look at the code.
>  
>
"dumb nat" is also triggered in ip_route_output, loops should not occur 
because
ipt_REJECT gives packets directly to ip_route_output2. a reason might be 
ip_route_input
doing policy checks, namely it checks if forwarding is configured on the 
receiving interface.

>You have a firewall-rule of which an incoming packet would trigger a new
>packet, which might trigger a firewall-rule to trigger an other packet...
>etc. But maybe I'm wrong, I'm not familair with the code (yet ?).
>

i've attached a patch which uses ip_route_input for tcp_resets in 
ipt_REJECT.
would you care to test it ? i confirmed it rejects correctly without 
policy routing,
but i have a very simple setup here so no good testing ..
The patch adds a call to ip_route_input after the ip_route_output for 
non-local
sources. The call to ip_route_output is still necesarry so we know an 
interface
where the source ip may actually have entered, otherwise it would only work
with reverse-path filters turned off.

@netfilter-people: would something like this be acceptable ? REJECT and 
MIRROR
(which looks broken wrt ip_route_output and dst handling) need something
like this to work correctly with policy routing.

Bye
Patrick


[-- Attachment #2: ipt_REJECT-tcprst-route.diff --]
[-- Type: text/plain, Size: 1176 bytes --]

===== ipt_REJECT.c 1.10 vs edited =====
--- 1.10/net/ipv4/netfilter/ipt_REJECT.c	Mon Mar 31 17:00:55 2003
+++ edited/ipt_REJECT.c	Mon Apr 14 23:00:54 2003
@@ -66,11 +66,26 @@
 
 	/* Routing: if not headed for us, route won't like source */
 	if (ip_route_output(&rt, oldskb->nh.iph->daddr,
-			    local ? oldskb->nh.iph->saddr : 0,
-			    RT_TOS(oldskb->nh.iph->tos) | RTO_CONN,
-			    0) != 0)
+	                    local ? oldskb->nh.iph->saddr : 0,
+	                    RT_TOS(oldskb->nh.iph->tos), 0) != 0)
 		return;
 
+	/* if src is not local use ip_route_input to respect policy routing
+	 * decision. the call to ip_route_output is still necessary so we
+	 * have a interface where the ip may actually have entered.
+	 */
+	if (local == 0) {
+		struct dst_entry *out_dst = (struct dst_entry *)rt;
+		if (ip_route_input(oldskb, oldskb->nh.iph->saddr,
+		                  oldskb->nh.iph->daddr,
+		                  RT_TOS(oldskb->nh.iph->tos),
+                                  out_dst->dev) != 0)
+			return;
+		dst_release(out_dst);
+		rt = (struct rtable *)oldskb->dst;
+		dst_hold(&rt->u.dst);
+	}
+	
 	hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
 
 

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-14 21:09       ` Patrick McHardy
@ 2003-04-15  7:40         ` Harald Welte
  2003-04-15 14:16           ` Patrick McHardy
  0 siblings, 1 reply; 10+ messages in thread
From: Harald Welte @ 2003-04-15  7:40 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: leen, netfilter-devel

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

On Mon, Apr 14, 2003 at 11:09:44PM +0200, Patrick McHardy wrote:

> @netfilter-people: would something like this be acceptable ? REJECT and 
> MIRROR (which looks broken wrt ip_route_output and dst handling) need
> something like this to work correctly with policy routing.

I don't see a problem with your patch.  Please note, however, that I am
not very familiar with the linux routing code - so I feel a bit unable
to make that decision.

We should talk to David Miller about this issue.  Could you please write
a short summary like 'old behaviour was X and we had Problem Y with it,
now we try to fix it with this patch doing Z'?  I would then put the
patch together with this summary (as .help file) in patch-o-matic
pending and discuss it with davem.

> Bye
> Patrick

-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-15  7:40         ` Harald Welte
@ 2003-04-15 14:16           ` Patrick McHardy
  2003-04-16  0:20             ` Patrick McHardy
  0 siblings, 1 reply; 10+ messages in thread
From: Patrick McHardy @ 2003-04-15 14:16 UTC (permalink / raw)
  To: Harald Welte; +Cc: leen, netfilter-devel

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

Hi Harald,
this is an updated version, description follows below.
If davem gives his blessing i will make a patch for MIRROR as well.

Harald Welte wrote:

>We should talk to David Miller about this issue.  Could you please write
>a short summary like 'old behaviour was X and we had Problem Y with it,
>now we try to fix it with this patch doing Z'?  I would then put the
>patch together with this summary (as .help file) in patch-o-matic
>pending and discuss it with davem.
>

Ok here it goes:

ipt_REJECT uses saddr=0 for lookups with ip_route_output for non-local ips,
therefore routing rules like "from a.b.c.d/x" don't apply for tcp-resets 
generated
by ipt_REJECT.

This patch makes reject call ip_route_output to find an interface where 
the source
ip may have come from (for reverse-path filters) and then call 
ip_route_input with
the source/dest address of the tcp-reset. It also fixes a bug introduced 
by last fix
for asym. routing, source and dest were switched so ip_route_output 
returned a
route in the wrong direction.

Best regards,
Patrick


[-- Attachment #2: ipt_REJECT-tcprst-route.diff --]
[-- Type: text/plain, Size: 1544 bytes --]

===== net/ipv4/netfilter/ipt_REJECT.c 1.10 vs edited =====
--- 1.10/net/ipv4/netfilter/ipt_REJECT.c	Mon Mar 31 17:00:55 2003
+++ edited/net/ipv4/netfilter/ipt_REJECT.c	Tue Apr 15 15:55:36 2003
@@ -11,7 +11,6 @@
 #include <net/icmp.h>
 #include <net/ip.h>
 #include <net/tcp.h>
-struct in_device;
 #include <net/route.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_REJECT.h>
@@ -64,12 +63,29 @@
 			 csum_partial((char *)otcph, otcplen, 0)) != 0)
 		return;
 
-	/* Routing: if not headed for us, route won't like source */
-	if (ip_route_output(&rt, oldskb->nh.iph->daddr,
-			    local ? oldskb->nh.iph->saddr : 0,
-			    RT_TOS(oldskb->nh.iph->tos) | RTO_CONN,
-			    0) != 0)
+	if (local) {
+		if (ip_route_output(&rt, oldskb->nh.iph->saddr,
+		                    oldskb->nh.iph->daddr,
+				    RT_TOS(oldskb->nh.iph->tos), 0) != 0)
 		return;
+	} else {
+		/* non-local source - we use ip_route_input to respect policy
+		 * routing rules. the call to ip_route_output is necessary to
+		 * get a valid interface where the source may have come from.
+		 */ 
+		if (ip_route_output(&rt, oldskb->nh.iph->daddr, 0, 0, 0) != 0)
+			return;
+		if (ip_route_input(oldskb, oldskb->nh.iph->saddr,
+		                   oldskb->nh.iph->daddr,
+				   RT_TOS(oldskb->nh.iph->tos),
+				   rt->u.dst.dev) != 0) {
+			dst_release(&rt->u.dst);
+			return;
+		}
+		dst_release(&rt->u.dst);
+		rt = (struct rtable *)oldskb->dst;
+		dst_hold(&rt->u.dst);
+	}
 
 	hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
 

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

* Re: Bug (?) in ipt_reject doesn't follow policy routing (2.4.x)
  2003-04-15 14:16           ` Patrick McHardy
@ 2003-04-16  0:20             ` Patrick McHardy
  0 siblings, 0 replies; 10+ messages in thread
From: Patrick McHardy @ 2003-04-16  0:20 UTC (permalink / raw)
  To: Harald Welte; +Cc: leen, netfilter-devel

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

This is a once-again-updated patch, i discovered two memory leaks,
one introduced by my patch and one from asym. routing fix. Both
are fixed in this version.

Bye,
Patrick


[-- Attachment #2: ipt_REJECT-route.diff --]
[-- Type: text/plain, Size: 2078 bytes --]

diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
--- a/net/ipv4/netfilter/ipt_REJECT.c	Wed Apr 16 02:14:52 2003
+++ b/net/ipv4/netfilter/ipt_REJECT.c	Wed Apr 16 02:14:52 2003
@@ -11,7 +11,6 @@
 #include <net/icmp.h>
 #include <net/ip.h>
 #include <net/tcp.h>
-struct in_device;
 #include <net/route.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_REJECT.h>
@@ -40,6 +39,7 @@
 	struct sk_buff *nskb;
 	struct tcphdr *otcph, *tcph;
 	struct rtable *rt;
+	struct dst_entry *odst;
 	unsigned int otcplen;
 	u_int16_t tmp_port;
 	u_int32_t tmp_addr;
@@ -64,12 +64,30 @@
 			 csum_partial((char *)otcph, otcplen, 0)) != 0)
 		return;
 
-	/* Routing: if not headed for us, route won't like source */
-	if (ip_route_output(&rt, oldskb->nh.iph->daddr,
-			    local ? oldskb->nh.iph->saddr : 0,
-			    RT_TOS(oldskb->nh.iph->tos) | RTO_CONN,
-			    0) != 0)
-		return;
+	if (local) {
+		if (ip_route_output(&rt, oldskb->nh.iph->saddr,
+		                    oldskb->nh.iph->daddr,
+				    RT_TOS(oldskb->nh.iph->tos), 0) != 0)
+			return;
+	} else {
+		/* non-local source - we use ip_route_input to respect policy
+		 * routing rules. the call to ip_route_output is necessary to
+		 * get a valid interface where the source ip may have come from.
+		 */ 
+		if (ip_route_output(&rt, oldskb->nh.iph->daddr, 0, 0, 0) != 0)
+			return;
+		odst = oldskb->dst;
+		if (ip_route_input(oldskb, oldskb->nh.iph->saddr,
+		                   oldskb->nh.iph->daddr,
+				   RT_TOS(oldskb->nh.iph->tos),
+				   rt->u.dst.dev) != 0) {
+			dst_release(&rt->u.dst);
+			return;
+		}
+		dst_release(&rt->u.dst);
+		rt = (struct rtable *)oldskb->dst;
+		oldskb->dst = odst;
+	}
 
 	hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
 
@@ -80,8 +98,10 @@
 	   hh_len of incoming interface < hh_len of outgoing interface */
 	nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
 			       GFP_ATOMIC);
-	if (!nskb)
+	if (!nskb) {
+		dst_release(&rt->u.dst);
 		return;
+	}
 
 	dst_release(nskb->dst);
 	nskb->dst = &rt->u.dst;

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

end of thread, other threads:[~2003-04-16  0:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-13 18:53 Bug (?) in ipt_reject doesn't follow policy routing (2.4.x) Leen Besselink
2003-04-13 20:13 ` Leen Besselink
2003-04-14  7:27   ` Leen Besselink
2003-04-14  7:59 ` Patrick Schaaf
2003-04-14  8:49   ` Patrick McHardy
2003-04-14 11:35     ` Leen Besselink
2003-04-14 21:09       ` Patrick McHardy
2003-04-15  7:40         ` Harald Welte
2003-04-15 14:16           ` Patrick McHardy
2003-04-16  0:20             ` Patrick McHardy

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.