Re: 2.1.102: ipchains: REJECT does only DENY - network gurus please
Sun, 17 May 1998 17:18:12 +0200

[cc'ed to Alexey Kuznetsov, because he is the routing guru]

On Sun, May 17, 1998 at 04:29:12PM +0200, Steffen Zahn wrote:
> >>>>> "Andi" == Andi Kleen <> writes:
> Andi> What it says - there is no output route for iph->saddr. Can you
> Andi> ping What is the actual value of saddr/iph->saddr
> Andi> on this place?
> Yes, I can ping (client taliesin) from (server zahn).
> netstat -r gives:
> Kernel IP routing table
> Destination Gateway Genmask Flags MSS Window irtt Iface
> * U 0 0 0 eth0
> May 17 16:15:32 zahn vmunix: icmp_send: ip_route_output(&rt, iph->saddr 200A8C0, saddr 14040C2, RT_TOS(tos), 0)
> This means iph->saddr is, saddr is .
> was the destination of the original packet that I want
> to reject here.
> There is currently no route to the address,
> only when I am connected to my ISP, that is also the reason why I want to
> reject that packet using ipchains.

Why use firewalling at all then? The forwarder will send a DEST_UNREACHable
when it can't find a route automatically. In extreme cases you could use
a reject route.

ip_route_output rejects the packet because it has no route to the source
address. When ip_route_input can't find a route for an incoming packet
it redirects the packets to the local interface and creates a temporary
routing cache entry. This entry has the RTCF_LOCAL flag set. Now icmp.c
has this check:

saddr = iph->daddr;
if (!(rt->rt_flags&RTCF_LOCAL))
saddr = 0;

meaning that saddr will contain the not routable address and when
ip_route_output() sees the martian address it'll return an error and
no ICMP is send.

Possible fixes:
1) Don't do that. With workaround as outlined above [always create routes
for your firewall rules, and use reject routes for the rest]
2) Remove the check from icmp.c. This means icmps in reply to packets for
the local host might carry the wrong source address (of a different interface).
3) Define a new flag RTCF_BADROUTE that is set by ip_route_input in the
no_route case and change the icmp.c check to:

saddr = iph->daddr;
if ((rt->rt_flags & (RTCF_LOCAL|RTCF_BADROUTE)) != RTCF_LOCAL)
saddr = 0;

(3) is probably the best solution, but it is really worth to care
about this weird case? Alexey, what do you mean?


To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to