Bill Fink wrote:
Marco,
On Tue, 20 Dec 2005 12:34:25 +0100, "Marco Berizzi" <pupilla@xxxxxxxxxxx>
wrote:
> Good morning Bill.
> I think I have found the "feature":
/proc/sys/net/ipv4/conf/*/log_martians
> Enabling it and then dmesging I see:
>
> Dec 20 10:18:42 Pleiadi kernel: martian source
'HDSL_public_network_host'
> from 'ADSL_IP', on dev eth0
> Dec 20 10:18:42 Pleiadi kernel: ll header:
> 00:60:97:d8:e5:01:00:07:50:7e:65:e0:08:00
>
> So I think linux will drop these packets anyway (they will even not
reach
> netfilter I think):
> may anyone confirm this?
Yes. I wonder
if you see this in the IP statistics of "netstat -s".
No I don't see these packets (icmp counters aren't incrementing) running
netstat -s on the firewall box.
The above messages from dmesg are printed by ip_handle_martian_source()
in net/ipv4/route.c, and if you get this far, it's all over.
ip_handle_martian_source() is called in 2 places, one from
__mkroute_input()
and the other from ip_route_input_slow(), both in route.c.
Here's the code from __mkroute_input():
err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
in_dev->dev, &spec_dst, &itag);
if (err < 0) {
ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
saddr);
err = -EINVAL;
goto cleanup;
}
And the code from ip_route_input_slow():
e_inval:
err = -EINVAL;
goto done;
e_nobufs:
err = -ENOBUFS;
goto done;
martian_source:
ip_handle_martian_source(dev, in_dev, skb, daddr, saddr);
goto e_inval;
So in both cases of calling ip_handle_martian_source(), the immediate
subsequent action is to simply error out with -EINVAL.
I don't think any of the "goto martian_source;" statements in
ip_route_input_slow() actually apply in this case, so that leaves
the call to ip_handle_martian_source() in __mkroute_input() as the
likely culprit.
The key there is fib_validate_source() returning a negative error
condition thus causing ip_handle_martian_source() to be called.
Here are the comments before the fib_validate_source() function
in net/ipv4/fib_frontend.c:
/* Given (packet source, input interface) and optional (dst, oif, tos):
- (main) check, that source is valid i.e. not broadcast or our local
address.
- figure out what "logical" interface this packet arrived
and calculate "specific destination" address.
- check, that packet arrived from expected physical interface.
*/
Given that you have disabled rp_filter on your system, it appears
that the only likely place in the fib_validate_source() function
that would return a negative error condition is this code near the
top of the function:
if (fib_lookup(&fl, &res))
goto last_resort;
if (res.type != RTN_UNICAST)
goto e_inval_res;
...
e_inval_res:
fib_res_put(&res);
e_inval:
return -EINVAL;
This code is doing a Forwarding Information Base lookup of the reverse
path since the flow fl is defined as the following earlier:
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = src,
.saddr = dst,
.tos = tos } },
.iif = oif };
In your specific case, this reverse path would be from your HDSL
public network host to the ADSL IP on your Linux box via the input
interface eth1.
I believe the error is being triggered because the destination address
of ADSL IP is a local address on your Linux box, and my best conjecture
is that res.type is thus RTN_LOCAL rather than RTN_UNICAST.
Thanks for the excellent explanation Bill. I haven't developer skills, but
now things are much more cleaner for me.
I have an idea for a possible code change,
perhaps controlled via sysctl? ;-)
but since I'm not sure of
all the possible code paths and interactions, I couldn't really vouch
for its correctness or even that it wouldn't possibly crash or hang
your system if it wasn't correct.
Perhaps IMO a better place for this last sentence would be net-devel.
Thanks again.
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html