svn commit: r185785 - in user/kmacy/head_arpv2/sys: net netinet
netinet6
Kip Macy
kmacy at FreeBSD.org
Mon Dec 8 20:54:18 PST 2008
Author: kmacy
Date: Tue Dec 9 04:54:17 2008
New Revision: 185785
URL: http://svn.freebsd.org/changeset/base/185785
Log:
- remove a number of cases of IF_AFDATA_LOCK recursion
- implement LLE_EXCLUSIVE
- implement LLE_FREE
Modified:
user/kmacy/head_arpv2/sys/net/if_llatbl.c
user/kmacy/head_arpv2/sys/net/if_llatbl.h
user/kmacy/head_arpv2/sys/net/if_var.h
user/kmacy/head_arpv2/sys/netinet/if_ether.c
user/kmacy/head_arpv2/sys/netinet/in.c
user/kmacy/head_arpv2/sys/netinet/ip_output.c
user/kmacy/head_arpv2/sys/netinet6/icmp6.c
user/kmacy/head_arpv2/sys/netinet6/in6.c
user/kmacy/head_arpv2/sys/netinet6/nd6.c
user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c
Modified: user/kmacy/head_arpv2/sys/net/if_llatbl.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_llatbl.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/net/if_llatbl.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -213,10 +213,10 @@ lla_rt_output(struct rt_msghdr *rtm, str
log(LOG_INFO, "%s: RTM_ADD publish "
"(proxy only) is invalid\n",
__func__);
- rtfree(rt);
+ RTFREE(rt);
return EINVAL;
}
- rtfree(rt);
+ RTFREE(rt);
flags |= LLE_PROXY;
}
Modified: user/kmacy/head_arpv2/sys/net/if_llatbl.h
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_llatbl.h Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/net/if_llatbl.h Tue Dec 9 04:54:17 2008 (r185785)
@@ -77,6 +77,7 @@ struct llentry {
#define LLE_WUNLOCK(lle) rw_wunlock(&(lle)->lle_lock)
#define LLE_RUNLOCK(lle) rw_runlock(&(lle)->lle_lock)
#define LLE_DOWNGRADE(lle) rw_downgrade(&(lle)->lle_lock)
+#define LLE_TRY_UPGRADE(lle) rw_try_upgrade(&(lle)->lle_lock)
#define LLE_LOCK_INIT(lle) rw_init_flags(&(lle)->lle_lock, "lle", RW_DUPOK)
#define LLE_WLOCK_ASSERT(lle) rw_assert(&(lle)->lle_lock, RA_WLOCKED)
@@ -105,6 +106,18 @@ struct llentry {
lle = 0; \
} while (0)
+#define LLE_FREE(lle) do { \
+ LLE_WLOCK(lle); \
+ if ((lle)->lle_refcnt <= 1) \
+ (lle)->lle_tbl->llt_free((lle)->lle_tbl, (lle));\
+ else { \
+ (lle)->lle_refcnt--; \
+ LLE_WUNLOCK(lle); \
+ } \
+ /* guard against invalid refs */ \
+ lle = 0; \
+} while (0)
+
#define ln_timer_ch lle_timer.ln_timer_ch
#define la_timer lle_timer.la_timer
Modified: user/kmacy/head_arpv2/sys/net/if_var.h
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_var.h Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/net/if_var.h Tue Dec 9 04:54:17 2008 (r185785)
@@ -359,13 +359,15 @@ typedef void (*group_change_event_handle
EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
#define IF_AFDATA_LOCK_INIT(ifp) \
- mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, \
- (MTX_DEF | MTX_RECURSE))
+ mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
#define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx)
#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx)
#define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx)
#define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx)
+#define IF_AFDATA_LOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_mtx, MA_OWNED)
+#define IF_AFDATA_UNLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_mtx, MA_NOTOWNED)
+
#define IFF_LOCKGIANT(ifp) do { \
if ((ifp)->if_flags & IFF_NEEDSGIANT) \
mtx_lock(&Giant); \
Modified: user/kmacy/head_arpv2/sys/netinet/if_ether.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet/if_ether.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet/if_ether.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -156,15 +156,22 @@ arptimer(void *arg)
return;
}
ifp = lle->lle_tbl->llt_ifp;
- IF_AFDATA_LOCK(ifp);
if ((lle->la_flags & LLE_DELETED) ||
(time_second >= lle->la_expire)) {
+ printf("deleting entry\n");
+
+ IF_AFDATA_LOCK(ifp);
if (!callout_pending(&lle->la_timer) &&
(callout_active(&lle->la_timer))) {
(void)llentry_free(lle);
}
+ IF_AFDATA_UNLOCK(ifp);
+ } else {
+ /*
+ * Still valid, just drop our reference
+ */
+ LLE_FREE(lle);
}
- IF_AFDATA_UNLOCK(ifp);
}
@@ -251,6 +258,7 @@ arpresolve(struct ifnet *ifp, struct rte
u_int flags;
int error;
+ log(LOG_DEBUG, "arpesolve called\n");
*lle = NULL;
if (m != NULL) {
if (m->m_flags & M_BCAST) {
@@ -280,11 +288,12 @@ arpresolve(struct ifnet *ifp, struct rte
"arpresolve: can't allocate llinfo for %s\n",
inet_ntoa(SIN(dst)->sin_addr));
m_freem(m);
+ log(LOG_DEBUG, "arpesolve: lla_lookup fail\n");
return (EINVAL);
}
- if (la->la_flags & LLE_VALID &&
- (la->la_flags & LLE_STATIC || la->la_expire > time_uptime)) {
+ if ((la->la_flags & LLE_VALID) &&
+ ((la->la_flags & LLE_STATIC) || (la->la_expire > time_uptime))) {
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
/*
* If entry has an expiry time and it is approaching,
@@ -297,12 +306,18 @@ arpresolve(struct ifnet *ifp, struct rte
&SIN(dst)->sin_addr, IF_LLADDR(ifp));
la->la_preempt--;
- }
+ }
+ log(LOG_DEBUG, "arpresolve: success\n");
+
*lle = la;
error = 0;
goto done;
- }
-
+ } else
+ log(LOG_DEBUG,
+ "la=%p valid=%d static=%d expire=%ld uptime=%ld\n", la,
+ !!(la->la_flags & LLE_VALID), !!(la->la_flags & LLE_STATIC),
+ la->la_expire, time_uptime);
+
if (la->la_flags & LLE_STATIC) { /* should not happen! */
log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n",
inet_ntoa(SIN(dst)->sin_addr));
@@ -319,7 +334,8 @@ arpresolve(struct ifnet *ifp, struct rte
if (la->la_hold)
m_freem(la->la_hold);
la->la_hold = m;
- LLE_DOWNGRADE(la);
+ if (!(la->la_asked == 0 || la->la_expire != time_uptime))
+ LLE_DOWNGRADE(la);
}
/*
* Return EWOULDBLOCK if we have tried less than arp_maxtries. It
@@ -334,12 +350,17 @@ arpresolve(struct ifnet *ifp, struct rte
(rt0->rt_flags & RTF_GATEWAY) ? EHOSTDOWN : EHOSTUNREACH;
if (la->la_asked == 0 || la->la_expire != time_uptime) {
+ log(LOG_DEBUG,
+ "arpresolve: kicking off new resolve expire=%ld\n",
+ la->la_expire);
+ LLE_ADDREF(la);
la->la_expire = time_uptime;
callout_reset(&la->la_timer, hz, arptimer, la);
la->la_asked++;
-
+ LLE_WUNLOCK(la);
arprequest(ifp, NULL, &SIN(dst)->sin_addr,
IF_LLADDR(ifp));
+ return (error);
}
done:
@@ -435,6 +456,7 @@ in_arpinput(struct mbuf *m)
struct in_addr isaddr, itaddr, myaddr;
u_int8_t *enaddr = NULL;
int op, flags;
+ struct mbuf *m0;
/*
, rif_len;
*/
@@ -529,6 +551,7 @@ in_arpinput(struct mbuf *m)
if (!bridged || (ia = TAILQ_FIRST(&V_in_ifaddrhead)) == NULL)
goto drop;
match:
+ log(LOG_DEBUG,"in_arpinput: match\n");
if (!enaddr)
enaddr = (u_int8_t *)IF_LLADDR(ifp);
myaddr = ia->ia_addr.sin_addr;
@@ -567,12 +590,13 @@ match:
la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
IF_AFDATA_UNLOCK(ifp);
if (la != NULL) {
+ log(LOG_DEBUG, "in_arpinput: la found\n");
/* the following is not an error when doing bridging */
if (!bridged && la->lle_tbl->llt_ifp != ifp
#ifdef DEV_CARP
&& (ifp->if_type != IFT_CARP || !carp_match)
#endif
- ) {
+ ) {
if (log_arp_wrong_iface)
log(LOG_ERR, "arp: %s is on %s "
"but got reply from %*D on %s\n",
@@ -582,9 +606,9 @@ match:
ifp->if_xname);
goto reply;
}
-
- if (la->la_flags & LLE_VALID &&
+ if ((la->la_flags & LLE_VALID) &&
bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
+ log(LOG_DEBUG, "LLE_VALID and match\n");
if (la->la_flags & LLE_STATIC) {
log(LOG_ERR,
"arp: %*D attempts to modify permanent "
@@ -603,6 +627,7 @@ match:
ifp->if_xname);
}
}
+
if (ifp->if_addrlen != ah->ar_hln) {
log(LOG_WARNING,
"arp from %*D: addr len: new %d, i/f %d (ignored)",
@@ -613,6 +638,7 @@ match:
(void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
la->la_flags |= LLE_VALID;
+ log(LOG_DEBUG, "in_arpinput: la=%p valid set\n", la);
if (!(la->la_flags & LLE_STATIC)) {
la->la_expire = time_uptime + arpt_keep;
callout_reset(&la->la_timer, hz * V_arpt_keep,
@@ -621,8 +647,13 @@ match:
la->la_asked = 0;
la->la_preempt = V_arp_maxtries;
if (la->la_hold) {
- (*ifp->if_output)(ifp, la->la_hold, L3_ADDR(la), NULL);
+ m0 = la->la_hold;
la->la_hold = 0;
+ memcpy(&sa, L3_ADDR(la), sizeof(sa));
+ LLE_WUNLOCK(la);
+
+ (*ifp->if_output)(ifp, m0, &sa, NULL);
+ return;
}
}
reply:
@@ -639,7 +670,6 @@ reply:
goto drop;
sin.sin_addr = itaddr;
-
/* XXX MRT use table 0 for arp reply */
rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
if (!rt)
@@ -650,12 +680,12 @@ reply:
* over who claims what Ether address.
*/
if (rt->rt_ifp == ifp) {
- rtfree(rt);
+ RTFREE(rt);
goto drop;
}
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
- rtfree(rt);
+ RTFREE(rt);
/*
* Also check that the node which sent the ARP packet
@@ -674,10 +704,10 @@ reply:
" from %s via %s, expecting %s\n",
inet_ntoa(isaddr), ifp->if_xname,
rt->rt_ifp->if_xname);
- rtfree(rt);
+ RTFREE(rt);
goto drop;
}
- rtfree(rt);
+ RTFREE(rt);
#ifdef DEBUG_PROXY
printf("arp: proxying for %s\n",
Modified: user/kmacy/head_arpv2/sys/netinet/in.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet/in.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet/in.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -1077,10 +1077,10 @@ in_lltable_rtcheck(struct ifnet *ifp, co
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
if (rt != NULL)
- rtfree(rt);
- return EINVAL;
+ RTFREE_LOCKED(rt);
+ return (EINVAL);
}
- rtfree(rt);
+ RTFREE_LOCKED(rt);
return 0;
}
@@ -1110,17 +1110,14 @@ in_lltable_lookup(struct lltable *llt, u
break;
}
- if (lle != NULL ) {
- if (flags & LLE_DELETE) {
- LLE_WLOCK(lle);
- lle->la_flags = LLE_DELETED;
- LLE_WUNLOCK(lle);
+ 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);
+ log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
#endif
- lle = NULL;
- } else
- LLE_RLOCK(lle);
+ lle = NULL;
} else {
#ifdef INVARIANTS
if (flags & LLE_DELETE)
@@ -1150,9 +1147,14 @@ in_lltable_lookup(struct lltable *llt, u
lle->lle_tbl = llt;
lle->lle_head = lleh;
- LLE_RLOCK(lle);
LIST_INSERT_HEAD(lleh, lle, lle_next);
}
+ if (lle) {
+ if (flags & LLE_EXCLUSIVE)
+ LLE_WLOCK(lle);
+ else
+ LLE_RLOCK(lle);
+ }
done:
return (lle);
}
Modified: user/kmacy/head_arpv2/sys/netinet/ip_output.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet/ip_output.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet/ip_output.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -567,11 +567,8 @@ passout:
* to avoid confusing lower layers.
*/
m->m_flags &= ~(M_PROTOFLAGS);
-
- IF_AFDATA_LOCK(ifp);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
- IF_AFDATA_UNLOCK(ifp);
goto done;
}
@@ -604,10 +601,8 @@ passout:
*/
m->m_flags &= ~(M_PROTOFLAGS);
- IF_AFDATA_LOCK(ifp);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, ro->ro_rt);
- IF_AFDATA_UNLOCK(ifp);
} else
m_freem(m);
}
Modified: user/kmacy/head_arpv2/sys/netinet6/icmp6.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet6/icmp6.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet6/icmp6.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -2583,17 +2583,16 @@ icmp6_redirect_output(struct mbuf *m0, s
IF_AFDATA_LOCK(ifp);
ln = nd6_lookup(router_ll6, 0, ifp);
- if (!ln) {
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_UNLOCK(ifp);
+ if (!ln)
goto nolladdropt;
- }
+
len = sizeof(*nd_opt) + ifp->if_addrlen;
len = (len + 7) & ~7; /* round by 8 */
/* safety check */
- if (len + (p - (u_char *)ip6) > maxlen) {
- IF_AFDATA_UNLOCK(ifp);
+ if (len + (p - (u_char *)ip6) > maxlen)
goto nolladdropt;
- }
+
if (ln->la_flags & LLE_VALID) {
nd_opt = (struct nd_opt_hdr *)p;
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
@@ -2602,7 +2601,7 @@ icmp6_redirect_output(struct mbuf *m0, s
bcopy(&ln->ll_addr, lladdr, ifp->if_addrlen);
p += len;
}
- IF_AFDATA_UNLOCK(ifp);
+ LLE_RUNLOCK(ln);
}
nolladdropt:;
Modified: user/kmacy/head_arpv2/sys/netinet6/in6.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet6/in6.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet6/in6.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -2215,10 +2215,23 @@ in6_lltable_lookup(struct lltable *llt,
lle->lle_head = lleh;
LIST_INSERT_HEAD(lleh, lle, lle_next);
} else {
- if (flags & LLE_DELETE)
+ 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);
+ else
+ LLE_RLOCK(lle);
}
- return lle;
+ return (lle);
}
static int
Modified: user/kmacy/head_arpv2/sys/netinet6/nd6.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet6/nd6.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet6/nd6.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -840,8 +840,12 @@ nd6_purge(struct ifnet *ifp)
nd6_setdefaultiface(0);
if (!V_ip6_forwarding && V_ip6_accept_rtadv) { /* XXX: too restrictive? */
- /* refresh default router list */
+ /* refresh default router list
+ *
+ *
+ */
defrouter_select();
+
}
/* XXXXX
@@ -851,21 +855,11 @@ nd6_purge(struct ifnet *ifp)
* from if_detach() where everything gets purged. So let
* in6_domifdetach() do the actual L2 table purging work.
*/
-#if 0
- /*
- * Nuke neighbor cache entries for the ifp.
- * Note that rt->rt_ifp may not be the same as ifp,
- * due to KAME goto ours hack. See RTM_RESOLVE case in
- * nd6_rtrequest(), and ip6_input().
- */
- IF_AFDATA_LOCK(ifp);
- lltable_free(LLTABLE6(ifp));
- IF_AFDATA_UNLOCK(ifp);
-#endif
}
/* Qing
* the caller acquires and releases the lock on the lltbls
+ * Returns the llentry locked
*/
struct llentry *
nd6_lookup(struct in6_addr *addr6, int flags, struct ifnet *ifp)
@@ -880,6 +874,8 @@ nd6_lookup(struct in6_addr *addr6, int f
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = *addr6;
+ IF_AFDATA_LOCK_ASSERT(ifp);
+
if (flags & ND6_CREATE)
llflags |= LLE_CREATE;
if (flags & ND6_EXCLUSIVE)
@@ -890,6 +886,7 @@ nd6_lookup(struct in6_addr *addr6, int f
ln->ln_state = ND6_LLINFO_NOSTATE;
callout_init(&ln->ln_timer_ch, 0);
}
+
return (ln);
}
@@ -978,7 +975,8 @@ nd6_is_addr_neighbor(struct sockaddr_in6
{
struct llentry *lle;
int rc = 0;
-
+
+ IF_AFDATA_UNLOCK_ASSERT(ifp);
if (nd6_is_new_addr_neighbor(addr, ifp))
return (1);
@@ -1401,6 +1399,8 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
int flags = 0;
int newstate = 0;
+ IF_AFDATA_LOCK_ASSERT(ifp);
+
if (ifp == NULL)
panic("ifp == NULL in nd6_cache_lladdr");
if (from == NULL)
@@ -1598,16 +1598,27 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
* for those are not autoconfigured hosts, we explicitly avoid such
* cases for safety.
*/
- if (do_update && ln->ln_router && !V_ip6_forwarding && V_ip6_accept_rtadv)
+ if (do_update && ln->ln_router && !V_ip6_forwarding && V_ip6_accept_rtadv) {
+#ifdef notyet
+ /*
+ * XXX implement the boiler plate
+ */
+ taskqueue_enqueue(ipv6_taskq, defrouter_select_task);
+#endif
+ /*
+ * guaranteed recursion
+ */
defrouter_select();
+ }
+
done:
if (ln) {
- if (ln->la_flags & LLE_STATIC)
- ln = NULL;
if (lladdr)
LLE_WUNLOCK(ln);
else
LLE_RUNLOCK(ln);
+ if (ln->la_flags & LLE_STATIC)
+ ln = NULL;
}
return (ln);
}
@@ -1680,7 +1691,9 @@ nd6_output(struct ifnet *ifp, struct ifn
* or an anycast address(i.e. not a multicast).
*/
flags = m ? LLE_EXCLUSIVE : 0;
+ IF_AFDATA_LOCK(rt->rt_ifp);
ln = lla_lookup(LLTABLE6(ifp), 0, (struct sockaddr *)dst);
+ IF_AFDATA_UNLOCK(rt->rt_ifp);
if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp)) {
/*
* Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
@@ -1688,7 +1701,9 @@ nd6_output(struct ifnet *ifp, struct ifn
* it is tolerable, because this should be a rare case.
*/
flags = ND6_CREATE | (m ? ND6_EXCLUSIVE : 0);
+ IF_AFDATA_LOCK(rt->rt_ifp);
ln = nd6_lookup(&dst->sin6_addr, flags, ifp);
+ IF_AFDATA_UNLOCK(rt->rt_ifp);
}
if (ln == NULL) {
if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
@@ -1700,7 +1715,6 @@ nd6_output(struct ifnet *ifp, struct ifn
ip6_sprintf(ip6buf, &dst->sin6_addr), ln, rt);
senderr(EIO); /* XXX: good error? */
}
-
goto sendpkt; /* send anyway */
}
@@ -1786,6 +1800,12 @@ nd6_output(struct ifnet *ifp, struct ifn
error = ENETDOWN; /* better error? */
goto bad;
}
+ if (ln) {
+ if (m0)
+ LLE_WUNLOCK(ln);
+ else
+ LLE_RUNLOCK(ln);
+ }
#ifdef MAC
mac_netinet6_nd6_send(ifp, m);
Modified: user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c Tue Dec 9 04:30:47 2008 (r185784)
+++ user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c Tue Dec 9 04:54:17 2008 (r185785)
@@ -115,7 +115,7 @@ nd6_ns_input(struct mbuf *m, int off, in
struct ifaddr *ifa = NULL;
int lladdrlen = 0;
int anycast = 0, proxy = 0, tentative = 0;
- int tlladdr;
+ int tlladdr, error;
union nd_opts ndopts;
struct sockaddr_dl *proxydl = NULL;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
@@ -169,7 +169,8 @@ nd6_ns_input(struct mbuf *m, int off, in
src_sa6.sin6_family = AF_INET6;
src_sa6.sin6_len = sizeof(src_sa6);
src_sa6.sin6_addr = saddr6;
- if (!nd6_is_addr_neighbor(&src_sa6, ifp)) {
+ error = nd6_is_addr_neighbor(&src_sa6, ifp);
+ if (error) {
nd6log((LOG_INFO, "nd6_ns_input: "
"NS packet from non-neighbor\n"));
goto bad;
@@ -701,8 +702,8 @@ nd6_na_input(struct mbuf *m, int off, in
*/
IF_AFDATA_LOCK(ifp);
ln = nd6_lookup(&taddr6, 0, ifp);
+ IF_AFDATA_UNLOCK(ifp);
if (ln == NULL) {
- IF_AFDATA_UNLOCK(ifp);
goto freeit;
}
@@ -712,7 +713,6 @@ nd6_na_input(struct mbuf *m, int off, in
* discard the packet.
*/
if (ifp->if_addrlen && lladdr == NULL) {
- IF_AFDATA_UNLOCK(ifp);
goto freeit;
}
@@ -786,7 +786,6 @@ nd6_na_input(struct mbuf *m, int off, in
ln->ln_state = ND6_LLINFO_STALE;
nd6_llinfo_settimer(ln, (long)V_nd6_gctimer * hz);
}
- IF_AFDATA_UNLOCK(ifp);
goto freeit;
} else if (is_override /* (2a) */
|| (!is_override && (lladdr != NULL && !llchange)) /* (2b) */
@@ -883,8 +882,6 @@ nd6_na_input(struct mbuf *m, int off, in
nd6_output(ifp, ifp, m_hold, L3_ADDR_SIN6(ln), NULL);
}
}
- IF_AFDATA_UNLOCK(ifp);
-
freeit:
m_freem(m);
return;
More information about the svn-src-user
mailing list