From owner-svn-src-user@FreeBSD.ORG Wed Dec 10 00:54:22 2008 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 33C371065670; Wed, 10 Dec 2008 00:54:22 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1F66F8FC26; Wed, 10 Dec 2008 00:54:22 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBA0sLYk007334; Wed, 10 Dec 2008 00:54:21 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBA0sL3P007331; Wed, 10 Dec 2008 00:54:21 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200812100054.mBA0sL3P007331@svn.freebsd.org> From: Kip Macy Date: Wed, 10 Dec 2008 00:54:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r185815 - in user/kmacy/head_arpv2/sys: netinet netinet6 X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Dec 2008 00:54:22 -0000 Author: kmacy Date: Wed Dec 10 00:54:21 2008 New Revision: 185815 URL: http://svn.freebsd.org/changeset/base/185815 Log: - add missed radix node head lock acquisition when calling - only acquire llentry lock exclusively when lookup fails - fix lle lookup Modified: user/kmacy/head_arpv2/sys/netinet/if_ether.c user/kmacy/head_arpv2/sys/netinet/in.c user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c Modified: user/kmacy/head_arpv2/sys/netinet/if_ether.c ============================================================================== --- user/kmacy/head_arpv2/sys/netinet/if_ether.c Wed Dec 10 00:08:25 2008 (r185814) +++ user/kmacy/head_arpv2/sys/netinet/if_ether.c Wed Dec 10 00:54:21 2008 (r185815) @@ -256,7 +256,7 @@ arpresolve(struct ifnet *ifp, struct rte INIT_VNET_INET(ifp->if_vnet); struct llentry *la = 0; u_int flags; - int error; + int error, renew; log(LOG_DEBUG, "arpesolve called\n"); *lle = NULL; @@ -275,12 +275,12 @@ arpresolve(struct ifnet *ifp, struct rte } flags = (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) ? 0 : LLE_CREATE; - flags |= (m ? LLE_EXCLUSIVE : 0); /* XXXXX * Since this function returns an llentry, the * lock is held by the caller. */ +retry: la = lla_lookup(LLTABLE(ifp), flags, dst); if (la == NULL) { if (flags & LLE_CREATE) @@ -325,17 +325,27 @@ arpresolve(struct ifnet *ifp, struct rte error = EINVAL; goto done; } + + renew = (la->la_asked == 0 || la->la_expire != time_uptime); /* * There is an arptab entry, but no ethernet address * response yet. Replace the held mbuf with this * latest one. */ if (m) { + if ((flags & LLE_EXCLUSIVE) == 0) { + flags |= LLE_EXCLUSIVE; + LLE_RUNLOCK(la); + goto retry; + } if (la->la_hold) m_freem(la->la_hold); la->la_hold = m; - if (!(la->la_asked == 0 || la->la_expire != time_uptime)) + if (renew == 0) { + flags &= ~LLE_EXCLUSIVE; LLE_DOWNGRADE(la); + } + } /* * Return EWOULDBLOCK if we have tried less than arp_maxtries. It @@ -349,7 +359,7 @@ arpresolve(struct ifnet *ifp, struct rte error = (rt0->rt_flags & RTF_GATEWAY) ? EHOSTDOWN : EHOSTUNREACH; - if (la->la_asked == 0 || la->la_expire != time_uptime) { + if (renew) { log(LOG_DEBUG, "arpresolve: kicking off new resolve expire=%ld\n", la->la_expire); @@ -364,7 +374,10 @@ arpresolve(struct ifnet *ifp, struct rte } done: - LLE_RUNLOCK(la); + if (flags & LLE_EXCLUSIVE) + LLE_WUNLOCK(la); + else + LLE_RUNLOCK(la); return (error); } Modified: user/kmacy/head_arpv2/sys/netinet/in.c ============================================================================== --- user/kmacy/head_arpv2/sys/netinet/in.c Wed Dec 10 00:08:25 2008 (r185814) +++ user/kmacy/head_arpv2/sys/netinet/in.c Wed Dec 10 00:54:21 2008 (r185815) @@ -1109,16 +1109,7 @@ in_lltable_lookup(struct lltable *llt, u if (bcmp(L3_ADDR(lle), l3addr, sizeof(struct sockaddr_in)) == 0) break; } - - if ((lle != NULL) && (flags & LLE_DELETE)) { - LLE_WLOCK(lle); - lle->la_flags = LLE_DELETED; - LLE_WUNLOCK(lle); -#ifdef INVARIANTS - log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle); -#endif - lle = NULL; - } else { + if (lle == NULL) { #ifdef INVARIANTS if (flags & LLE_DELETE) log(LOG_INFO, "interface address is missing from cache = %p in delete\n", lle); @@ -1148,7 +1139,15 @@ in_lltable_lookup(struct lltable *llt, u lle->lle_tbl = llt; lle->lle_head = lleh; LIST_INSERT_HEAD(lleh, lle, lle_next); - } + } else if (flags & LLE_DELETE) { + LLE_WLOCK(lle); + lle->la_flags = LLE_DELETED; + LLE_WUNLOCK(lle); +#ifdef INVARIANTS + log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle); +#endif + lle = NULL; + } if (lle) { if (flags & LLE_EXCLUSIVE) LLE_WLOCK(lle); Modified: user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c ============================================================================== --- user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c Wed Dec 10 00:08:25 2008 (r185814) +++ user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c Wed Dec 10 00:54:21 2008 (r185815) @@ -476,10 +476,8 @@ defrouter_addreq(struct nd_defrouter *ne (struct sockaddr *)&gate, (struct sockaddr *)&mask, RTF_GATEWAY, &newrt); if (newrt) { - RT_LOCK(newrt); nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ - RT_REMREF(newrt); - RT_UNLOCK(newrt); + RTFREE(newrt); } if (error == 0) new->installed = 1; @@ -1549,6 +1547,7 @@ nd6_prefix_onlink(struct nd_prefix *pr) struct nd_prefix *opr; u_long rtflags; int error = 0; + struct radix_node_head *rnh; struct rtentry *rt = NULL; char ip6buf[INET6_ADDRSTRLEN]; struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; @@ -1632,6 +1631,8 @@ nd6_prefix_onlink(struct nd_prefix *pr) ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt); if (error == 0) { if (rt != NULL) /* this should be non NULL, though */ { + rnh = V_rt_tables[rt->rt_fibnum][AF_INET6]; + RADIX_NODE_HEAD_LOCK(rnh); RT_LOCK(rt); if (!rt_setgate(rt, rt_key(rt), (struct sockaddr *)&null_sdl)) { ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = @@ -1639,6 +1640,7 @@ nd6_prefix_onlink(struct nd_prefix *pr) ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = rt->rt_ifp->if_index; } + RADIX_NODE_HEAD_UNLOCK(rnh); nd6_rtmsg(RTM_ADD, rt); RT_UNLOCK(rt); }