Subject: kern/10482: proxy-arp requests are answered on the wrong interfaces (+fix)
To: None <firstname.lastname@example.org>
From: None <email@example.com>
Date: 06/29/2000 16:32:14
>Synopsis: proxy-arp requests are answered on the wrong interfaces (+fix)
>Arrival-Date: Thu Jun 29 16:33:00 PDT 2000
>Originator: Christian Limpach
NetBSD joblin.pin.lu 1.4.2 NetBSD 1.4.2 (REDBALL) #6: Sat Jun 10 18:49:55 CEST 2000 firstname.lastname@example.org:/usr/src/sys/arch/i386/compile/REDBALL i386
Proxy-arp entries are only valid for one interface since they include this interface's ether address. The proxy-arp support included in the kernel will answer arp request on all interfaces. It will send arp replies which include an ether address which is not reachable on all segments except on the one connected to the interface whose ether address is used. This will disturb the network startup of windows machines (and probably others) for which the proxy-arp is done as they use arp to check for duplicate ip addresses.
you need two segments: a.a.a.0/24 and b.b.b.0/24
the multihomed netbsd machine is rl0 connected to a.a.a.0/24 with address a.a.a.1 (ether address 00:00:aa:bb:cc:dd) and rl1 connected to b.b.b.0/24 with address b.b.b.1.
a windows machine is connected to the b.b.b.0/24 segment and has the addresses b.b.b.2 and also a a.a.a.0/24 address a.a.a.2 but it has no connection to the a.a.a.0/24 segment
the multihomed netbsd machine has the following proxy-arp entry:
? (a.a.a.2) at 00:00:aa:bb:cc:dd permanent published (proxy only)
and routing table entry:
a.a.a.2 b.b.b.2 UGHS .... rl1
the routing table entry is not necessary to repeat the problem but gives a vague idea what this setup is used for.
When the windows machine boots, it will send an arp-request which will be answered by netbsd on rl1 with the rl0 ether address 00:00:aa:bb:cc:dd. Windows will complain with a duplicate ip address error.
before sending a reply, check if the arp entry for the reply is associated to the interface we are going to send the reply on.
RCS file: /cvsroot/syssrc/sys/netinet/if_arp.c,v
retrieving revision 220.127.116.11
diff -c -r18.104.22.168 if_arp.c
*** if_arp.c 1999/06/20 19:20:33 22.214.171.124
--- if_arp.c 2000/06/29 23:00:37
*** 681,686 ****
--- 681,688 ----
if (la == 0)
rt = la->la_rt;
+ if (rt->rt_ifp != ifp)
+ goto out;
bcopy((caddr_t)ar_sha(ah), (caddr_t)ar_tha(ah), ah->ar_hln);
sdl = SDL(rt->rt_gateway);
bcopy(LLADDR(sdl), (caddr_t)ar_sha(ah), ah->ar_hln);