I have a variation of the multi-homed routing problem that I just can't figure out.

We have a site with two subnets, N1 and N2, where some hosts have an interface on both (in the picture below, B and C), and some only on N1 (i.e., host A) or N2 (i.e., host D).

---+--------------+--------------+---------------------- N1
   |              |              |                    
   |A1            |B1            |C1                   
+--+---+       +--+---+       +--+---+       +--+---+  
|      |       |      |       |      |       |      |  
|  A   |       |  B   |       |  C   |       |  D   |  
|      |       |      |       |      |       |      |  
+------+       +--+---+       +--+---+       +--+---+  
                  |B2            |C2            |D2    
                  |              |              |      
------------------+--------------+--------------+------- N2

Host B serves as a gateway to network N2 for hosts that are only on N1. This works fine for getting to most places, except when trying to talk to hosts that have an interface on both networks. That is, if host A pings host D or host C at its address C1, everything works. If it pings at C2, I can see with tcpdump the ping arrives at C2, but I don't see it leave from any of C's interfaces.

Why does the response not get sent out? Is this a matter of routing tables or something else?


This is probably due to reverse path filtering. In short:

When a machine with reverse path filtering enabled receives a packet, the machine will first check whether the source of the received packet is reachable through the interface it came in.

  • If it is routable through the interface which it came, then the machine will accept the packet.
  • If it is not routable through the interface, which it came, then the machine will drop that packet.

As in the example you gave, host C receives a packet with source address A1 on its C2 interface; however the route from host C to A1 would go through the C1 interface. Hence the packet arrived at the "wrong" interface, and is dropped.

Execute the following command:

grep . /proc/sys/net/ipv4/conf/*/rp_filter

You probably see at least the C2 interface has the value "1", which means reverse path filtering is turned on.

You could turn this filtering off, but in your case probably the "loose mode filtering" is more appropriate: the incoming source address is checked against all interfaces and if it matches any, it will be accepted even though it strictly came in on the wrong interface. In this case you need to use the value "2". To apply this to all interfaces:

for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 2 > $i; done

See the ip-sysctl.txt file supplied with the kernel sources, or online at www.kernel.org and check the rp_filter description there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.