Re: double packet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Marco,

On Wed, 21 Dec 2005, Marco Berizzi wrote:

> Bill Fink wrote:
> 
> >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,

I mocked this up in our lab.  I first verified that my theory was
correct, and it was.  In the fib_validate_source() function (in
net/ipv4/fib_frontend.c), after the first call to fib_lookup(),
res.type is RTN_LOCAL instead of RTN_UNICAST, and this causes
the e_inval_res error path to be taken, which returns -EINVAL.

Based on this, I tried the following patch (as stated earlier I can't
vouch for the complete correctness of this patch):

--------------------------------------------------------------------------------
--- .orig/fib_frontend.c	2005-11-24 17:10:21.000000000 -0500
+++ ./fib_frontend.c	2005-12-22 19:19:55.000000000 -0500
@@ -185,7 +185,7 @@
 
 	if (fib_lookup(&fl, &res))
 		goto last_resort;
-	if (res.type != RTN_UNICAST)
+	if ((res.type != RTN_UNICAST) && (res.type != RTN_LOCAL))
 		goto e_inval_res;
 	*spec_dst = FIB_RES_PREFSRC(res);
 	fib_combine_itag(itag, &res);
@@ -208,7 +208,7 @@
 
 	ret = 0;
 	if (fib_lookup(&fl, &res) == 0) {
-		if (res.type == RTN_UNICAST) {
+		if ((res.type == RTN_UNICAST) || (res.type == RTN_LOCAL)) {
 			*spec_dst = FIB_RES_PREFSRC(res);
 			ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
 		}
--------------------------------------------------------------------------------

This actually worked.  Packets were then forwarded out to the
HDSL public network, and the HDSL public network host then generated
an ICMP echo reply back to the ADSL IP, which I saw via tcpdump on
the Linux host on eth1.

Unfortunately this was as good as it got.  I believe this is because
the original POSTROUTING SNAT'ed packet went out eth0, and the reply
is coming back on eth1, and the two can't be reconciled to get the
reply to be sent back out eth2 to the original source host.

However, if you happen to have an unused ADSL public network IP address,
you can get this to work (I did), and then you wouldn't even need the
patch above.  Just SNAT the private IP address to this IP address
(call it ADSL NAT IP) instead of the ADSL IP of your Linux box.
You will also have to publish an ARP for the ADSL NAT IP on your
Linux box, mangle destinations for the ADSL NAT IP to be marked as 2,
causing your test routing table to be used, add a host route to your
test routing table for the ADSL NAT IP via your HDSL router IP, and
ACCEPT packets to or from the ADSL NAT IP in your FORWARD chain.

This will cause a symmetric path for the ICMP echos and replies
between your private host and your HDSL public network host, both
looped via the Internet and your two ISPs.  At least it worked for
me in our lab.

I hope this helps.

						-Bill
-
: 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

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux