svn commit: r185827 - user/kmacy/head_arpv2/sys/net
Kip Macy
kmacy at FreeBSD.org
Tue Dec 9 19:04:17 PST 2008
Author: kmacy
Date: Wed Dec 10 03:04:16 2008
New Revision: 185827
URL: http://svn.freebsd.org/changeset/base/185827
Log:
- ifp lookup only needs to be protected with an rlock
- lock lle exclusively for LLE_CREATE
- don't hold LLE_LOCK across arprequest
- only hold IF_AFDATA_LOCK across lookup
Modified:
user/kmacy/head_arpv2/sys/net/if_llatbl.c
Modified: user/kmacy/head_arpv2/sys/net/if_llatbl.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_llatbl.c Wed Dec 10 02:59:09 2008 (r185826)
+++ user/kmacy/head_arpv2/sys/net/if_llatbl.c Wed Dec 10 03:04:16 2008 (r185827)
@@ -188,7 +188,8 @@ lla_rt_output(struct rt_msghdr *rtm, str
struct ifnet *ifp;
struct lltable *llt;
struct llentry *lle;
- u_int flags = 0;
+ u_int laflags = 0, flags = 0;
+ int error = 0;
if (dl == NULL || dl->sdl_family != AF_LINK) {
log(LOG_INFO, "%s: invalid dl\n", __func__);
@@ -240,17 +241,21 @@ lla_rt_output(struct rt_msghdr *rtm, str
* XXXXXXXX:
* REVISE this approach if possible.
*/
- IFNET_WLOCK();
+ IFNET_RLOCK();
SLIST_FOREACH(llt, &lltables, llt_link) {
if (llt->llt_af == dst->sa_family &&
llt->llt_ifp == ifp)
break;
}
- IFNET_WUNLOCK();
+ IFNET_RUNLOCK();
KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
+ if (flags && LLE_CREATE)
+ flags |= LLE_EXCLUSIVE;
+
IF_AFDATA_LOCK(ifp);
lle = lla_lookup(llt, flags, dst);
+ IF_AFDATA_UNLOCK(ifp);
if (lle != NULL) {
if (flags & LLE_CREATE) {
/* qing: if we delay the delete, then if a subsequent
@@ -270,31 +275,32 @@ lla_rt_output(struct rt_msghdr *rtm, str
/*
* "arp" and "ndp" always sets the (RTF_STATIC | RTF_HOST) flags
*/
+
if (rtm->rtm_rmx.rmx_expire == 0) {
lle->la_flags |= LLE_STATIC;
lle->la_expire = 0;
} else
lle->la_expire = rtm->rtm_rmx.rmx_expire;
+ laflags = lle->la_flags;
+ LLE_WUNLOCK(lle);
#ifdef INET
/* gratuious ARP */
- if ((lle->la_flags & LLE_PUB) &&
+ if ((laflags & LLE_PUB) &&
dst->sa_family == AF_INET) {
arprequest(ifp,
&((struct sockaddr_in *)dst)->sin_addr,
&((struct sockaddr_in *)dst)->sin_addr,
- ((lle->la_flags & LLE_PROXY) ?
+ ((laflags & LLE_PROXY) ?
(u_char *)IF_LLADDR(ifp) :
(u_char *)LLADDR(dl)));
}
#endif
- }
+ } else
+ LLE_RUNLOCK(lle);
} else {
- if (flags & LLE_DELETE) {
- IF_AFDATA_UNLOCK(ifp);
- return EINVAL;
- }
+ if (flags & LLE_DELETE)
+ error = EINVAL;
}
- IF_AFDATA_UNLOCK(ifp);
- return 0;
+ return (error);
}
More information about the svn-src-user
mailing list