Module Name:    src
Committed By:   roy
Date:           Tue Oct 13 09:33:35 UTC 2015

Modified Files:
        src/sys/netinet: if_arp.c

Log Message:
Simplify la handling in arpresolve() by asking arplookup() not to create
a la. If a la is needed arpresolve() will then create it or mark the
current la as writable.


To generate a diff of this commit:
cvs rdiff -u -r1.184 -r1.185 src/sys/netinet/if_arp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.184 src/sys/netinet/if_arp.c:1.185
--- src/sys/netinet/if_arp.c:1.184	Thu Oct  8 08:17:37 2015
+++ src/sys/netinet/if_arp.c	Tue Oct 13 09:33:35 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.184 2015/10/08 08:17:37 roy Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.185 2015/10/13 09:33:35 roy Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.184 2015/10/08 08:17:37 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.185 2015/10/13 09:33:35 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -791,26 +791,17 @@ arpresolve(struct ifnet *ifp, struct rte
 {
 	struct llentry *la;
 	const struct sockaddr_dl *sdl;
-	int renew;
-	int flags = 0;
+	const char *create_lookup;
+	bool renew;
 	int error;
 
 	KASSERT(m != NULL);
 
-	la = arplookup(ifp, m, &satocsin(dst)->sin_addr, 1, 0, 0, rt);
-	if (la != NULL)
-		rt = la->la_rt;
+	la = arplookup(ifp, m, &satocsin(dst)->sin_addr, 0, 0, 0, rt);
+	if (la == NULL || la->la_rt == NULL)
+		goto notfound;
 
-	if (la == NULL || rt == NULL) {
-		ARP_STATINC(ARP_STAT_ALLOCFAIL);
-		log(LOG_DEBUG,
-		    "arpresolve: can't allocate llinfo on %s for %s\n",
-		    ifp->if_xname, in_fmtaddr(satocsin(dst)->sin_addr));
-		m_freem(m);
-		if (la != NULL)
-			LLE_RUNLOCK(la);
-		return 0;
-	}
+	rt = la->la_rt;
 	sdl = satocsdl(rt->rt_gateway);
 	/*
 	 * Check the address family and length is valid, the address
@@ -837,69 +828,82 @@ arpresolve(struct ifnet *ifp, struct rte
 	}
 #endif
 
-retry:
+notfound:
 	if (la == NULL) {
-		IF_AFDATA_RLOCK(ifp);
-		la = lla_lookup(LLTABLE(ifp), flags, dst);
-		IF_AFDATA_RUNLOCK(ifp);
-	}
-
 #ifdef IFF_STATICARP /* FreeBSD */
 #define _IFF_NOARP (IFF_NOARP | IFF_STATICARP)
 #else
 #define _IFF_NOARP IFF_NOARP
 #endif
-	if ((la == NULL) && ((flags & LLE_EXCLUSIVE) == 0)
-	    && ((ifp->if_flags & _IFF_NOARP) == 0))
-	{
-		flags |= LLE_EXCLUSIVE;
+		if (ifp->if_flags & _IFF_NOARP) {
+			m_freem(m);
+			return 0;
+		}
+#undef _IFF_NOARP
+		create_lookup = "create";
 		IF_AFDATA_WLOCK(ifp);
-		la = lla_create(LLTABLE(ifp), flags, dst);
+		la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
 		IF_AFDATA_WUNLOCK(ifp);
-
-		if (la == NULL) {
-			log(LOG_DEBUG,
-			    "%s: failed to create llentry for %s on %s\n",
-			    __func__, inet_ntoa(satocsin(dst)->sin_addr),
-			    ifp->if_xname);
-		}
+		if (la == NULL)
+			ARP_STATINC(ARP_STAT_ALLOCFAIL);
+	} else if (LLE_TRY_UPGRADE(la) == 0) {
+		create_lookup = "lookup";
+		LLE_RUNLOCK(la);
+		IF_AFDATA_RLOCK(ifp);
+		la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
+		IF_AFDATA_RUNLOCK(ifp);
 	}
-#undef _IFF_NOARP
 
 	if (la == NULL) {
+		log(LOG_DEBUG,
+		    "%s: failed to %s llentry for %s on %s\n",
+		    __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr),
+		    ifp->if_xname);
 		m_freem(m);
 		return 0;
 	}
 
+	/* Just in case */
+	if (la->la_rt == NULL) {
+		log(LOG_DEBUG,
+		    "%s: valid llentry has no rtentry for %s on %s\n",
+		    __func__, inet_ntoa(satocsin(dst)->sin_addr),
+		    ifp->if_xname);
+		m_freem(m);
+		return 0;
+	}
+	rt = la->la_rt;
+
 	if ((la->la_flags & LLE_VALID) &&
-	    ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
+	    ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime))
+	{
+		sdl = satocsdl(rt->rt_gateway);
 		memcpy(desten, CLLADDR(sdl),
 		    min(sdl->sdl_alen, ifp->if_addrlen));
-		renew = 0;
+		renew = false;
 		/*
 		 * If entry has an expiry time and it is approaching,
 		 * see if we need to send an ARP request within this
 		 * arpt_down interval.
 		 */
 		if (!(la->la_flags & LLE_STATIC) &&
-		    time_uptime + la->la_preempt > la->la_expire) {
-			renew = 1;
+		    time_uptime + la->la_preempt > la->la_expire)
+		{
+			renew = true;
 			la->la_preempt--;
 		}
 
-		if (flags & LLE_EXCLUSIVE)
-			LLE_WUNLOCK(la);
-		else
-			LLE_RUNLOCK(la);
+		LLE_WUNLOCK(la);
 
-		if (renew == 1) {
+		if (renew) {
 			const u_int8_t *enaddr =
 #if NCARP > 0
 			    (rt->rt_ifp->if_type == IFT_CARP) ?
 			    CLLADDR(rt->rt_ifp->if_sadl):
 #endif
 			    CLLADDR(ifp->if_sadl);
-			arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
+			arprequest(ifp,
+			    &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
 			    &satocsin(dst)->sin_addr, enaddr);
 		}
 
@@ -915,12 +919,6 @@ retry:
 	}
 
 	renew = (la->la_asked == 0 || la->la_expire != time_uptime);
-	if (renew && (flags & LLE_EXCLUSIVE) == 0) {
-		flags |= LLE_EXCLUSIVE;
-		LLE_RUNLOCK(la);
-		la = NULL;
-		goto retry;
-	}
 
 	/*
 	 * There is an arptab entry, but no ethernet address
@@ -946,10 +944,8 @@ retry:
 	} else
 		la->la_hold = m;
 	la->la_numheld++;
-	if (renew == 0 && (flags & LLE_EXCLUSIVE)) {
-		flags &= ~LLE_EXCLUSIVE;
+	if (!renew)
 		LLE_DOWNGRADE(la);
-	}
 
 	/*
 	 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
@@ -975,19 +971,15 @@ retry:
 		callout_reset(&la->la_timer, hz * arpt_down,
 		    arptimer, la);
 		la->la_asked++;
-		if (flags & LLE_EXCLUSIVE)
-			LLE_WUNLOCK(la);
-		else
-			LLE_RUNLOCK(la);
+		LLE_WUNLOCK(la);
+
 		arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
 		    &satocsin(dst)->sin_addr, enaddr);
 		return error == 0;
 	}
 done:
-	if (flags & LLE_EXCLUSIVE)
-		LLE_WUNLOCK(la);
-	else
-		LLE_RUNLOCK(la);
+	LLE_RUNLOCK(la);
+
 	return error == 0;
 }
 

Reply via email to