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