diff options
author | glebius <glebius@FreeBSD.org> | 2005-09-09 10:06:27 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-09-09 10:06:27 +0000 |
commit | f609e1ae48b25702b91f73d6ccb1cfefcf5a4d5f (patch) | |
tree | c26edc3a1c6681707558759552ff100e9704f6b4 | |
parent | 044310140d19ff0446c5718f045a8b841b3ad079 (diff) | |
download | FreeBSD-src-f609e1ae48b25702b91f73d6ccb1cfefcf5a4d5f.zip FreeBSD-src-f609e1ae48b25702b91f73d6ccb1cfefcf5a4d5f.tar.gz |
- Do not hold route entry lock, when calling arprequest(). One such
call was introduced by me in 1.139, the other one was present before.
- Do all manipulations with rtentry and la before dropping the lock.
- Copy interface address from route into local variable before dropping
the lock. Supply this copy as argument to arprequest()
LORs fixed:
http://sources.zabbadoz.net/freebsd/lor/003.html
http://sources.zabbadoz.net/freebsd/lor/037.html
http://sources.zabbadoz.net/freebsd/lor/061.html
http://sources.zabbadoz.net/freebsd/lor/062.html
http://sources.zabbadoz.net/freebsd/lor/064.html
http://sources.zabbadoz.net/freebsd/lor/068.html
http://sources.zabbadoz.net/freebsd/lor/071.html
http://sources.zabbadoz.net/freebsd/lor/074.html
http://sources.zabbadoz.net/freebsd/lor/077.html
http://sources.zabbadoz.net/freebsd/lor/093.html
http://sources.zabbadoz.net/freebsd/lor/135.html
http://sources.zabbadoz.net/freebsd/lor/140.html
http://sources.zabbadoz.net/freebsd/lor/142.html
http://sources.zabbadoz.net/freebsd/lor/145.html
http://sources.zabbadoz.net/freebsd/lor/152.html
http://sources.zabbadoz.net/freebsd/lor/158.html
-rw-r--r-- | sys/netinet/if_ether.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 63ea545..24c8b98 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -445,6 +445,9 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, */ if ((rt->rt_expire == 0 || rt->rt_expire > time_second) && sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { + + bcopy(LLADDR(sdl), desten, sdl->sdl_alen); + /* * If entry has an expiry time and it is approaching, * see if we need to send an ARP request within this @@ -452,14 +455,16 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, */ if ((rt->rt_expire != 0) && (time_second + la->la_preempt > rt->rt_expire)) { - arprequest(ifp, - &SIN(rt->rt_ifa->ifa_addr)->sin_addr, - &SIN(dst)->sin_addr, - IF_LLADDR(ifp)); + struct in_addr sin = + SIN(rt->rt_ifa->ifa_addr)->sin_addr; + la->la_preempt--; + RT_UNLOCK(rt); + arprequest(ifp, &sin, &SIN(dst)->sin_addr, + IF_LLADDR(ifp)); + return (0); } - bcopy(LLADDR(sdl), desten, sdl->sdl_alen); RT_UNLOCK(rt); return (0); } @@ -487,10 +492,13 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, if (la->la_asked == 0 || rt->rt_expire != time_second) { rt->rt_expire = time_second; if (la->la_asked++ < arp_maxtries) { - arprequest(ifp, - &SIN(rt->rt_ifa->ifa_addr)->sin_addr, - &SIN(dst)->sin_addr, - IF_LLADDR(ifp)); + struct in_addr sin = + SIN(rt->rt_ifa->ifa_addr)->sin_addr; + + RT_UNLOCK(rt); + arprequest(ifp, &sin, &SIN(dst)->sin_addr, + IF_LLADDR(ifp)); + return (EWOULDBLOCK); } else { rt->rt_flags |= RTF_REJECT; rt->rt_expire += arpt_down; |