Subject: RTM_ADD and overwriting arp entries
To: None <tech-net@netbsd.org>
From: David Brownlee <abs@formula1.com>
List: tech-net
Date: 08/17/2001 20:05:41
RTM_ADD will not overwrite an existing (partial) arp entry.
My guess is this behaviour was introduced around 1.4 with the
new media independent arp subsystem.
This is a problem for netbooting machines with bootroms that do
not respond to arp (a sun IPC is a good example). If a partial arp
entry is present rarpd will not be able to replace it, and when
the client tries to tftp the bootloader the server will just sit
there sending out arp requests until the arp entry is manually
deleted (or everything is killed and it times out).
I've run up a trivial patch to make rarpd explicitly delete an
existing arp entry before RTM_ADD.
Does anyone have any better suggestions?
Index: mkarp.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/rarpd/mkarp.c,v
retrieving revision 1.3
diff -u -B -r1.3 mkarp.c
--- mkarp.c 2000/02/11 11:27:20 1.3
+++ mkarp.c 2001/08/17 19:06:54
@@ -152,7 +152,9 @@
!(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
case IFT_ISO88024: case IFT_ISO88025: case IFT_ARCNET:
- goto overwrite;
+ /* race condition if arp between DELETE and ADD */
+ rtmsg(RTM_DELETE, s, rtm, &sin_m, &sdl_m);
+ goto add_arp;
}
#if 0
(void)printf("set: can only proxy for %s\n", host);
@@ -160,7 +162,7 @@
close(s);
return (1);
}
-overwrite:
+add_arp:
if (sdl->sdl_family != AF_LINK) {
#if 0
(void)printf("cannot intuit interface index and type for %s\n",
@@ -197,6 +200,8 @@
pid = getpid();
+ if (cmd == RTM_DELETE)
+ goto doit;
(void)memset(&m_rtmsg, 0, sizeof(m_rtmsg));
rtm->rtm_version = RTM_VERSION;
@@ -225,7 +230,7 @@
NEXTADDR(RTA_GATEWAY, sdl_m);
rtm->rtm_msglen = cp - (char *)&m_rtmsg;
-
+doit:
l = rtm->rtm_msglen;
rtm->rtm_seq = ++seq;
rtm->rtm_type = cmd;
--
David/absolute abs@formula1.com