diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index a5d2017..8a78a69 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1836,6 +1836,7 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, struct sockaddr_in6 *dst, struct rtentry *rt0, struct llentry *lle, struct mbuf **chain) { + struct route ro; struct mbuf *m = m0; struct m_tag *mtag; struct llentry *ln = lle; @@ -2012,10 +2013,10 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, * an llentry */ if ((ln != NULL) && (lle == NULL)) { - if (flags & LLE_EXCLUSIVE) - LLE_WUNLOCK(ln); - else - LLE_RUNLOCK(ln); + if (flags & LLE_EXCLUSIVE) { + LLE_DOWNGRADE(ln); + flags &= ~LLE_EXCLUSIVE; + } } #ifdef MAC @@ -2039,7 +2040,7 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, ip6len); /* -1 == no app on SEND socket */ if (error == 0 || error != -1) - return (error); + goto out; } } @@ -2066,16 +2067,19 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, } return (error); } + bzero(&ro, sizeof(ro)); + ro.ro_lle = ln; /* Reset layer specific mbuf flags to avoid confusing lower layers. */ m->m_flags &= ~(M_PROTOFLAGS); - if ((ifp->if_flags & IFF_LOOPBACK) != 0) { - return ((*ifp->if_output)(origifp, m, (struct sockaddr *)dst, - NULL)); - } - error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, NULL); - return (error); + if ((ifp->if_flags & IFF_LOOPBACK) != 0) + error = (*ifp->if_output)(origifp, m, (struct sockaddr *)dst, + &ro); + else + error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, &ro); +out: + m = NULL; - bad: +bad: /* * ln is valid and the caller did not pass in * an llentry