Problem Description: 1 ethernet interface IP (eth0): 192.168.128.16 netmask 255.255.255.0 1 loopback address IP (lo:2): 1.1.1.1 netmask 255.255.255.255 1 route to 2.2.2.2 through 192.168.128.60 A packet is sent from machine with IP 2.2.2.2 to the linux machine to dst IP 1.1.1.1 (lo:2) through ethernet interface (eth0). When linux machine tries to find out the mac address of 192.168.128.60 with ARP, it uses the loopback IP address (lo:2) as source insted of the IP address of the ethernet interface (eth0). tcpdump output: > tcpdump -nei eth0 arp or host 2.2.2.2 tcpdump: listening on eth0 00:29:38.385849 0:c:85:1f:a3:d6 0:48:54:6a:3a:dd 0800 64: 2.2.2.2.55302 > 1.1.1.1.23: S 4186612861:4186612861(0) win 4128 <mss 1460> (DF) [tos 0xc0] 00:29:38.386200 0:48:54:6a:3a:dd ff:ff:ff:ff:ff:ff 0806 42: arp who-has 192.168.128.60 tell 1.1.1.1 00:29:39.385310 0:48:54:6a:3a:dd ff:ff:ff:ff:ff:ff 0806 42: arp who-has 192.168.128.60 tell 1.1.1.1 ifconfig output: > ifconfig -a eth0 Link encap:Ethernet HWaddr 00:48:54:6A:3A:DD inet addr:192.168.128.16 Bcast:192.168.128.255 Mask:255.255.255.0 inet6 addr: fe80::248:54ff:fe6a:3add/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2695 errors:0 dropped:0 overruns:0 frame:0 TX packets:2829 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:308510 (301.2 Kb) TX bytes:353754 (345.4 Kb) Interrupt:15 Base address:0xe000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:379 errors:0 dropped:0 overruns:0 frame:0 TX packets:379 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:136862 (133.6 Kb) TX bytes:136862 (133.6 Kb) lo:2 Link encap:Local Loopback inet addr:1.1.1.1 Mask:255.255.255.255 UP LOOPBACK RUNNING MTU:16436 Metric:1 route print: > ip route list 2.2.2.2 via 192.168.128.60 dev eth0 192.168.128.0/24 dev eth0 proto kernel scope link src 192.168.128.16 default via 192.168.128.200 dev eth0 mtu 300 arp table: > arp -a ? (192.168.128.202) at 00:30:B6:01:17:80 [ether] on eth0 router.newipnet.com (192.168.128.200) at 00:0C:85:1F:A3:D6 [ether] on eth0 ? (192.168.128.60) at <incomplete> on eth0 madre.newipnet.com (192.168.128.4) at 00:E0:7D:7B:D3:8E [ether] on eth0 Steps to reproduce: 1. Setup Loopback interface 2. clear arp table 3. setup a route in another PC to reach the loopback address through IP in ethernet interface in linux box. 4. use ping from another PC to the loopback ip address. 5. You can see the ARP requests with wrong ip source address in linux box with tcpdump or ethereal.
Created attachment 595 [details] Patch for ARP v1- Seems to work
It seems this to be a frequent problem with linux, behaviour changed from kernel versions: Linux kernel 2.0.xx doesn't do arp response on loopback alias and tunneling interfaces, it is good for the LVS cluster. However, Linux kernel 2.2.xx does all arp responses of all its IP addresses except the loopback addresses (127.0.0.0/255.0.0.0) and multicast addresses. http://www.linuxvirtualserver.org/docs/arp.html There's a hidden patch (thanks to Julian Anasatasov) that solves this problem (better patch than the one I have submitted): http://www.ssi.bg/~ja/#hidden http://www.ssi.bg/~ja/hidden.txt It seems that "normal" linux "shares" its interfaces. Julian and me have been working in a new patch for making interfaces to be "isolated" and make linux behave like other OSes and systems. I have called it "isolated patch". What it does? If output dev, isolated=0... we announce this dev IP through any input dev (normal linux behaviour) If output dev, isolated=1... we just announce this dev IP (ARP) if input dev == output dev, and you cannot reach this dev IP through another input dev unless forwarding=1 for input dev. How enabling it? First, you must apply the patch and recompile kernel. Second, you must enable the feature with: echo "1" >/proc/sys/net/ipv4/conf/all/isolated Third, you must enable the out dev where isolated is needed, or in every interface if you want linux behave like Solarius or other OSes: echo "1" >/proc/sys/net/ipv4/conf/lo/isolated echo "1" >/proc/sys/net/ipv4/conf/eth1/isolated Fourth, better you flush the route cache for changes to be inmediate: ip route flush cache It's all. Regards, Carlos Velasco
Created attachment 615 [details] isolated patch for kernel 2.4.21
Documentation/networking/ip-sysctl.txt: arp_announce - INTEGER Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface: 0 - (default) Use any local address, configured on any interface 1 - Try to avoid local addresses that are not in the target's subnet for this interface. This mode is useful when target hosts reachable via this interface require the source IP address in ARP requests to be part of their logical network configured on the receiving interface. When we generate the request we will check all our subnets that include the target IP and will preserve the source address if it is from such subnet. If there is no such subnet we select source address according to the rules for level 2. 2 - Always use the best local address for this target. In this mode we ignore the source address in the IP packet and try to select local address that we prefer for talks with the target host. Such local address is selected by looking for primary IP addresses on all our subnets on the outgoing interface that include the target IP address. If no suitable local address is found we select the first local address we have on the outgoing interface or on all other interfaces, with the hope we will receive reply for our request and even sometimes no matter the source IP address we announce. Can anyone close this report please? According to bugzilla I don't have the privileges.
@Patrick McHardy: you need to assign it first to be able to close it.