Date: Wed, 16 Sep 2015 19:56:16 +0300 From: Gleb Smirnoff <glebius@FreeBSD.org> To: "Alexander V. Chernikov" <melifaro@FreeBSD.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r287861 - in head/sys: net netinet6 netpfil/pf ofed/drivers/infiniband/ulp/ipoib Message-ID: <20150916165616.GP1023@FreeBSD.org> In-Reply-To: <201509161426.t8GEQTPJ028672@repo.freebsd.org> References: <201509161426.t8GEQTPJ028672@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi! The main disaster is still in its place in nd6_output_ifp(), as it was before in nd6_output():: error = (*ifp->if_output)(origifp, m, (struct sockaddr *)dst, NULL); ^^^ ^^^^^^^ :( On Wed, Sep 16, 2015 at 02:26:29PM +0000, Alexander V. Chernikov wrote: A> Author: melifaro A> Date: Wed Sep 16 14:26:28 2015 A> New Revision: 287861 A> URL: https://svnweb.freebsd.org/changeset/base/287861 A> A> Log: A> Simplify the way of attaching IPv6 link-layer header. A> A> Problem description: A> How do we currently perform layer 2 resolution and header imposition: A> A> For IPv4 we have the following chain: A> ip_output() -> (ether|atm|whatever)_output() -> arpresolve() A> A> Lookup is done in proper place (link-layer output routine) and it is possible A> to provide cached lle data. A> A> For IPv6 situation is more complex: A> ip6_output() -> nd6_output() -> nd6_output_ifp() -> (whatever)_output() -> A> nd6_storelladdr() A> A> We have ip6_ouput() which calls nd6_output() instead of link output routine. A> nd6_output() does the following: A> * checks if lle exists, creates it if needed (similar to arpresolve()) A> * performes lle state transitions (similar to arpresolve()) A> * calls nd6_output_ifp() which pushes packets to link output routine along A> with running SeND/MAC hooks regardless of lle state A> (e.g. works as run-hooks placeholder). A> A> After that, iface output routine like ether_output() calls nd6_storelladdr() A> which performs lle lookup once again. A> A> As a result, we perform lookup twice for each outgoing packet for most types A> of interfaces. We also need to maintain runtime-checked table of 'nd6-free' A> interfaces (see nd6_need_cache()). A> A> Fix this behavior by eliminating first ND lookup. To be more specific: A> * make all nd6_output() consumers use nd6_output_ifp() instead A> * rename nd6_output[_slow]() to nd6_resolve_[slow]() A> * convert nd6_resolve() and nd6_resolve_slow() to arpresolve() semantics, A> e.g. copy L2 address to buffer instead of pushing packet towards lower A> layers A> * Make all nd6_storelladdr() users use nd6_resolve() A> * eliminate nd6_storelladdr() A> A> The resulting callchain is the following: A> ip6_output() -> nd6_output_ifp() -> (whatever)_output() -> nd6_resolve() A> A> Error handling: A> Currently sending packet to non-existing la results in ip6_<output|forward> A> -> nd6_output() -> nd6_output _lle() which returns 0. A> In new scenario packet is propagated to <ether|whatever>_output() -> A> nd6_resolve() which will return EWOULDBLOCK, and that result A> will be converted to 0. A> A> (And EWOULDBLOCK is actually used by IB/TOE code). A> A> Sponsored by: Yandex LLC A> Differential Revision: https://reviews.freebsd.org/D1469 A> A> Modified: A> head/sys/net/if_arcsubr.c A> head/sys/net/if_ethersubr.c A> head/sys/net/if_fddisubr.c A> head/sys/net/if_fwsubr.c A> head/sys/net/if_iso88025subr.c A> head/sys/netinet6/ip6_forward.c A> head/sys/netinet6/ip6_output.c A> head/sys/netinet6/nd6.c A> head/sys/netinet6/nd6.h A> head/sys/netpfil/pf/pf.c A> head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c A> A> Modified: head/sys/net/if_arcsubr.c A> ============================================================================== A> --- head/sys/net/if_arcsubr.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/net/if_arcsubr.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -103,8 +103,8 @@ arc_output(struct ifnet *ifp, struct mbu A> u_int8_t atype, adst; A> int loop_copy = 0; A> int isphds; A> -#ifdef INET A> - int is_gw; A> +#if defined(INET) || defined(INET6) A> + int is_gw = 0; A> #endif A> A> if (!((ifp->if_flags & IFF_UP) && A> @@ -112,6 +112,11 @@ arc_output(struct ifnet *ifp, struct mbu A> return(ENETDOWN); /* m, m1 aren't initialized yet */ A> A> error = 0; A> +#if defined(INET) || defined(INET6) A> + if (ro != NULL && ro->ro_rt != NULL && A> + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) A> + is_gw = 1; A> +#endif A> A> switch (dst->sa_family) { A> #ifdef INET A> @@ -125,10 +130,6 @@ arc_output(struct ifnet *ifp, struct mbu A> else if (ifp->if_flags & IFF_NOARP) A> adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF; A> else { A> - is_gw = 0; A> - if (ro != NULL && ro->ro_rt != NULL && A> - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) A> - is_gw = 1; A> error = arpresolve(ifp, is_gw, m, dst, &adst, NULL); A> if (error) A> return (error == EWOULDBLOCK ? 0 : error); A> @@ -169,10 +170,11 @@ arc_output(struct ifnet *ifp, struct mbu A> case AF_INET6: A> if ((m->m_flags & M_MCAST) != 0) A> adst = arcbroadcastaddr; /* ARCnet broadcast address */ A> - else A> - error = nd6_storelladdr(ifp, m, dst, (u_char *)&adst, NULL); A> - if (error) A> - return (error); A> + else { A> + error = nd6_resolve(ifp, is_gw, m, dst, &adst, NULL); A> + if (error != 0) A> + return (error == EWOULDBLOCK ? 0 : error); A> + } A> atype = ARCTYPE_INET6; A> break; A> #endif A> A> Modified: head/sys/net/if_ethersubr.c A> ============================================================================== A> --- head/sys/net/if_ethersubr.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/net/if_ethersubr.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -225,10 +225,10 @@ ether_output(struct ifnet *ifp, struct m A> if (lle != NULL && (pflags & LLE_VALID)) A> memcpy(edst, &lle->ll_addr.mac16, sizeof(edst)); A> else A> - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, A> + error = nd6_resolve(ifp, is_gw, m, dst, (u_char *)edst, A> &pflags); A> if (error) A> - return error; A> + return (error == EWOULDBLOCK ? 0 : error); A> type = htons(ETHERTYPE_IPV6); A> break; A> #endif A> A> Modified: head/sys/net/if_fddisubr.c A> ============================================================================== A> --- head/sys/net/if_fddisubr.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/net/if_fddisubr.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -101,8 +101,8 @@ fddi_output(struct ifnet *ifp, struct mb A> int loop_copy = 0, error = 0, hdrcmplt = 0; A> u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN]; A> struct fddi_header *fh; A> -#ifdef INET A> - int is_gw; A> +#if defined(INET) || defined(INET6) A> + int is_gw = 0; A> #endif A> A> #ifdef MAC A> @@ -118,13 +118,15 @@ fddi_output(struct ifnet *ifp, struct mb A> senderr(ENETDOWN); A> getmicrotime(&ifp->if_lastchange); A> A> +#if defined(INET) || defined(INET6) A> + if (ro != NULL && ro->ro_rt != NULL && A> + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) A> + is_gw = 1; A> +#endif A> + A> switch (dst->sa_family) { A> #ifdef INET A> case AF_INET: { A> - is_gw = 0; A> - if (ro != NULL && ro->ro_rt != NULL && A> - (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) A> - is_gw = 1; A> error = arpresolve(ifp, is_gw, m, dst, edst, NULL); A> if (error) A> return (error == EWOULDBLOCK ? 0 : error); A> @@ -161,9 +163,9 @@ fddi_output(struct ifnet *ifp, struct mb A> #endif /* INET */ A> #ifdef INET6 A> case AF_INET6: A> - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); A> + error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL); A> if (error) A> - return (error); /* Something bad happened */ A> + return (error == EWOULDBLOCK ? 0 : error); A> type = htons(ETHERTYPE_IPV6); A> break; A> #endif /* INET6 */ A> A> Modified: head/sys/net/if_fwsubr.c A> ============================================================================== A> --- head/sys/net/if_fwsubr.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/net/if_fwsubr.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -89,8 +89,8 @@ firewire_output(struct ifnet *ifp, struc A> struct mbuf *mtail; A> int unicast, dgl, foff; A> static int next_dgl; A> -#ifdef INET A> - int is_gw; A> +#if defined(INET) || defined(INET6) A> + int is_gw = 0; A> #endif A> A> #ifdef MAC A> @@ -105,6 +105,11 @@ firewire_output(struct ifnet *ifp, struc A> goto bad; A> } A> A> +#if defined(INET) || defined(INET6) A> + if (ro != NULL && ro->ro_rt != NULL && A> + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) A> + is_gw = 1; A> +#endif A> /* A> * For unicast, we make a tag to store the lladdr of the A> * destination. This might not be the first time we have seen A> @@ -173,10 +178,10 @@ firewire_output(struct ifnet *ifp, struc A> #ifdef INET6 A> case AF_INET6: A> if (unicast) { A> - error = nd6_storelladdr(fc->fc_ifp, m, dst, A> + error = nd6_resolve(fc->fc_ifp, is_gw, m, dst, A> (u_char *) destfw, NULL); A> if (error) A> - return (error); A> + return (error == EWOULDBLOCK ? 0 : error); A> } A> type = ETHERTYPE_IPV6; A> break; A> A> Modified: head/sys/net/if_iso88025subr.c A> ============================================================================== A> --- head/sys/net/if_iso88025subr.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/net/if_iso88025subr.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -293,9 +293,9 @@ iso88025_output(struct ifnet *ifp, struc A> #endif /* INET */ A> #ifdef INET6 A> case AF_INET6: A> - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); A> + error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL); A> if (error) A> - return (error); A> + return (error == EWOULDBLOCK ? 0 : error); A> snap_type = ETHERTYPE_IPV6; A> break; A> #endif /* INET6 */ A> A> Modified: head/sys/netinet6/ip6_forward.c A> ============================================================================== A> --- head/sys/netinet6/ip6_forward.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/netinet6/ip6_forward.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -571,7 +571,7 @@ pass: A> goto bad; A> } A> A> - error = nd6_output(rt->rt_ifp, origifp, m, dst, rt); A> + error = nd6_output_ifp(rt->rt_ifp, origifp, m, dst); A> if (error) { A> in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard); A> IP6STAT_INC(ip6s_cantforward); A> A> Modified: head/sys/netinet6/ip6_output.c A> ============================================================================== A> --- head/sys/netinet6/ip6_output.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/netinet6/ip6_output.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -935,7 +935,7 @@ passout: A> m->m_pkthdr.len); A> ifa_free(&ia6->ia_ifa); A> } A> - error = nd6_output(ifp, origifp, m, dst, ro->ro_rt); A> + error = nd6_output_ifp(ifp, origifp, m, dst); A> goto done; A> } A> A> @@ -1034,7 +1034,7 @@ sendorfree: A> counter_u64_add(ia->ia_ifa.ifa_obytes, A> m->m_pkthdr.len); A> } A> - error = nd6_output(ifp, origifp, m, dst, ro->ro_rt); A> + error = nd6_output_ifp(ifp, origifp, m, dst); A> } else A> m_freem(m); A> } A> A> Modified: head/sys/netinet6/nd6.c A> ============================================================================== A> --- head/sys/netinet6/nd6.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/netinet6/nd6.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -136,10 +136,10 @@ static void nd6_free_redirect(const stru A> static void nd6_llinfo_timer(void *); A> static void clear_llinfo_pqueue(struct llentry *); A> static void nd6_rtrequest(int, struct rtentry *, struct rt_addrinfo *); A> -static int nd6_output_lle(struct ifnet *, struct ifnet *, struct mbuf *, A> - struct sockaddr_in6 *); A> -static int nd6_output_ifp(struct ifnet *, struct ifnet *, struct mbuf *, A> - struct sockaddr_in6 *); A> +static int nd6_resolve_slow(struct ifnet *, struct mbuf *, A> + const struct sockaddr_in6 *, u_char *, uint32_t *); A> +static int nd6_need_cache(struct ifnet *); A> + A> A> static VNET_DEFINE(struct callout, nd6_slowtimo_ch); A> #define V_nd6_slowtimo_ch VNET(nd6_slowtimo_ch) A> @@ -1904,7 +1904,7 @@ nd6_grab_holdchain(struct llentry *ln, s A> } A> } A> A> -static int A> +int A> nd6_output_ifp(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, A> struct sockaddr_in6 *dst) A> { A> @@ -1950,16 +1950,29 @@ nd6_output_ifp(struct ifnet *ifp, struct A> } A> A> /* A> - * IPv6 packet output - light version. A> - * Checks if destination LLE exists and is in proper state A> - * (e.g no modification required). If not true, fall back to A> - * "heavy" version. A> + * Do L2 address resolution for @sa_dst address. Stores found A> + * address in @desten buffer. Copy of lle ln_flags can be also A> + * saved in @pflags if @pflags is non-NULL. A> + * A> + * If destination LLE does not exists or lle state modification A> + * is required, call "slow" version. A> + * A> + * Return values: A> + * - 0 on success (address copied to buffer). A> + * - EWOULDBLOCK (no local error, but address is still unresolved) A> + * - other errors (alloc failure, etc) A> */ A> int A> -nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, A> - struct sockaddr_in6 *dst, struct rtentry *rt0) A> +nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m, A> + const struct sockaddr *sa_dst, u_char *desten, uint32_t *pflags) A> { A> struct llentry *ln = NULL; A> + const struct sockaddr_in6 *dst6; A> + A> + if (pflags != NULL) A> + *pflags = 0; A> + A> + dst6 = (const struct sockaddr_in6 *)sa_dst; A> A> /* discard the packet if IPv6 operation is disabled on the interface */ A> if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { A> @@ -1967,14 +1980,25 @@ nd6_output(struct ifnet *ifp, struct ifn A> return (ENETDOWN); /* better error? */ A> } A> A> - if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr)) A> - goto sendpkt; A> - A> - if (nd6_need_cache(ifp) == 0) A> - goto sendpkt; A> + if (m != NULL && m->m_flags & M_MCAST) { A> + switch (ifp->if_type) { A> + case IFT_ETHER: A> + case IFT_FDDI: A> + case IFT_L2VLAN: A> + case IFT_IEEE80211: A> + case IFT_BRIDGE: A> + case IFT_ISO88025: A> + ETHER_MAP_IPV6_MULTICAST(&dst6->sin6_addr, A> + desten); A> + return (0); A> + default: A> + m_freem(m); A> + return (EAFNOSUPPORT); A> + } A> + } A> A> IF_AFDATA_RLOCK(ifp); A> - ln = nd6_lookup(&dst->sin6_addr, 0, ifp); A> + ln = nd6_lookup(&dst6->sin6_addr, 0, ifp); A> IF_AFDATA_RUNLOCK(ifp); A> A> /* A> @@ -1990,45 +2014,33 @@ nd6_output(struct ifnet *ifp, struct ifn A> /* Fall back to slow processing path */ A> if (ln != NULL) A> LLE_RUNLOCK(ln); A> - return (nd6_output_lle(ifp, origifp, m, dst)); A> + return (nd6_resolve_slow(ifp, m, dst6, desten, pflags)); A> } A> A> -sendpkt: A> - if (ln != NULL) A> - LLE_RUNLOCK(ln); A> A> - return (nd6_output_ifp(ifp, origifp, m, dst)); A> + bcopy(&ln->ll_addr, desten, ifp->if_addrlen); A> + if (pflags != NULL) A> + *pflags = ln->la_flags; A> + LLE_RUNLOCK(ln); A> + return (0); A> } A> A> A> /* A> - * Output IPv6 packet - heavy version. A> - * Function assume that either A> - * 1) destination LLE does not exist, is invalid or stale, so A> - * ND6_EXCLUSIVE lock needs to be acquired A> - * 2) destination lle is provided (with ND6_EXCLUSIVE lock), A> - * in that case packets are queued in &chain. A> + * Do L2 address resolution for @sa_dst address. Stores found A> + * address in @desten buffer. Copy of lle ln_flags can be also A> + * saved in @pflags if @pflags is non-NULL. A> * A> + * Heavy version. A> + * Function assume that destination LLE does not exist, A> + * is invalid or stale, so ND6_EXCLUSIVE lock needs to be acquired. A> */ A> static int A> -nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, A> - struct sockaddr_in6 *dst) A> +nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m, A> + const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags) A> { A> struct llentry *lle = NULL, *lle_tmp; A> A> - KASSERT(m != NULL, ("NULL mbuf, nothing to send")); A> - /* discard the packet if IPv6 operation is disabled on the interface */ A> - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { A> - m_freem(m); A> - return (ENETDOWN); /* better error? */ A> - } A> - A> - if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr)) A> - goto sendpkt; A> - A> - if (nd6_need_cache(ifp) == 0) A> - goto sendpkt; A> - A> /* A> * Address resolution or Neighbor Unreachability Detection A> * for the next hop. A> @@ -2072,23 +2084,18 @@ nd6_output_lle(struct ifnet *ifp, struct A> } A> } A> if (lle == NULL) { A> - if ((ifp->if_flags & IFF_POINTOPOINT) == 0 && A> - !(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) { A> + if (!(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) { A> m_freem(m); A> return (ENOBUFS); A> } A> - goto sendpkt; /* send anyway */ A> + A> + if (m != NULL) A> + m_freem(m); A> + return (ENOBUFS); A> } A> A> LLE_WLOCK_ASSERT(lle); A> A> - /* We don't have to do link-layer address resolution on a p2p link. */ A> - if ((ifp->if_flags & IFF_POINTOPOINT) != 0 && A> - lle->ln_state < ND6_LLINFO_REACHABLE) { A> - lle->ln_state = ND6_LLINFO_STALE; A> - nd6_llinfo_settimer_locked(lle, (long)V_nd6_gctimer * hz); A> - } A> - A> /* A> * The first time we send a packet to a neighbor whose entry is A> * STALE, we have to change the state to DELAY and a sets a timer to A> @@ -2107,8 +2114,13 @@ nd6_output_lle(struct ifnet *ifp, struct A> * (i.e. its link-layer address is already resolved), just A> * send the packet. A> */ A> - if (lle->ln_state > ND6_LLINFO_INCOMPLETE) A> - goto sendpkt; A> + if (lle->ln_state > ND6_LLINFO_INCOMPLETE) { A> + bcopy(&lle->ll_addr, desten, ifp->if_addrlen); A> + if (pflags != NULL) A> + *pflags = lle->la_flags; A> + LLE_WUNLOCK(lle); A> + return (0); A> + } A> A> /* A> * There is a neighbor cache entry, but no ethernet address A> @@ -2160,13 +2172,7 @@ nd6_output_lle(struct ifnet *ifp, struct A> LLE_WUNLOCK(lle); A> } A> A> - return (0); A> - A> - sendpkt: A> - if (lle != NULL) A> - LLE_WUNLOCK(lle); A> - A> - return (nd6_output_ifp(ifp, origifp, m, dst)); A> + return (EWOULDBLOCK); A> } A> A> A> @@ -2192,15 +2198,12 @@ nd6_flush_holdchain(struct ifnet *ifp, s A> A> /* A> * XXX A> - * note that intermediate errors are blindly ignored - but this is A> - * the same convention as used with nd6_output when called by A> - * nd6_cache_lladdr A> + * note that intermediate errors are blindly ignored A> */ A> return (error); A> } A> A> - A> -int A> +static int A> nd6_need_cache(struct ifnet *ifp) A> { A> /* A> @@ -2297,61 +2300,6 @@ nd6_rem_ifa_lle(struct in6_ifaddr *ia, i A> lltable_delete_addr(LLTABLE6(ifp), LLE_IFADDR, saddr); A> } A> A> -/* A> - * the callers of this function need to be re-worked to drop A> - * the lle lock, drop here for now A> - */ A> -int A> -nd6_storelladdr(struct ifnet *ifp, struct mbuf *m, A> - const struct sockaddr *dst, u_char *desten, uint32_t *pflags) A> -{ A> - struct llentry *ln; A> - A> - if (pflags != NULL) A> - *pflags = 0; A> - IF_AFDATA_UNLOCK_ASSERT(ifp); A> - if (m != NULL && m->m_flags & M_MCAST) { A> - switch (ifp->if_type) { A> - case IFT_ETHER: A> - case IFT_FDDI: A> - case IFT_L2VLAN: A> - case IFT_IEEE80211: A> - case IFT_BRIDGE: A> - case IFT_ISO88025: A> - ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr, A> - desten); A> - return (0); A> - default: A> - m_freem(m); A> - return (EAFNOSUPPORT); A> - } A> - } A> - A> - A> - /* A> - * the entry should have been created in nd6_store_lladdr A> - */ A> - IF_AFDATA_RLOCK(ifp); A> - ln = lla_lookup(LLTABLE6(ifp), 0, dst); A> - IF_AFDATA_RUNLOCK(ifp); A> - if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) { A> - if (ln != NULL) A> - LLE_RUNLOCK(ln); A> - /* this could happen, if we could not allocate memory */ A> - m_freem(m); A> - return (1); A> - } A> - A> - bcopy(&ln->ll_addr, desten, ifp->if_addrlen); A> - if (pflags != NULL) A> - *pflags = ln->la_flags; A> - LLE_RUNLOCK(ln); A> - /* A> - * A *small* use after free race exists here A> - */ A> - return (0); A> -} A> - A> static void A> clear_llinfo_pqueue(struct llentry *ln) A> { A> A> Modified: head/sys/netinet6/nd6.h A> ============================================================================== A> --- head/sys/netinet6/nd6.h Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/netinet6/nd6.h Wed Sep 16 14:26:28 2015 (r287861) A> @@ -414,22 +414,19 @@ void nd6_llinfo_settimer_locked(struct l A> void nd6_timer(void *); A> void nd6_purge(struct ifnet *); A> void nd6_nud_hint(struct rtentry *, struct in6_addr *, int); A> -int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *, A> - struct sockaddr *, u_char *); A> +int nd6_resolve(struct ifnet *, int, struct mbuf *, A> + const struct sockaddr *, u_char *, uint32_t *); A> int nd6_ioctl(u_long, caddr_t, struct ifnet *); A> void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, A> char *, int, int, int); A> -int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *, A> - struct sockaddr_in6 *, struct rtentry *); A> void nd6_grab_holdchain(struct llentry *, struct mbuf **, A> struct sockaddr_in6 *); A> int nd6_flush_holdchain(struct ifnet *, struct ifnet *, struct mbuf *, A> struct sockaddr_in6 *); A> -int nd6_need_cache(struct ifnet *); A> int nd6_add_ifa_lle(struct in6_ifaddr *); A> void nd6_rem_ifa_lle(struct in6_ifaddr *, int); A> -int nd6_storelladdr(struct ifnet *, struct mbuf *, A> - const struct sockaddr *, u_char *, uint32_t *); A> +int nd6_output_ifp(struct ifnet *, struct ifnet *, struct mbuf *, A> + struct sockaddr_in6 *); A> A> /* nd6_nbr.c */ A> void nd6_na_input(struct mbuf *, int, int); A> A> Modified: head/sys/netpfil/pf/pf.c A> ============================================================================== A> --- head/sys/netpfil/pf/pf.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/netpfil/pf/pf.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -5534,7 +5534,7 @@ pf_route6(struct mbuf **m, struct pf_rul A> if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr)) A> dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index); A> if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) A> - nd6_output(ifp, ifp, m0, &dst, NULL); A> + nd6_output_ifp(ifp, ifp, m0, &dst); A> else { A> in6_ifstat_inc(ifp, ifs6_in_toobig); A> if (r->rt != PF_DUPTO) A> A> Modified: head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c A> ============================================================================== A> --- head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c Wed Sep 16 13:25:35 2015 (r287860) A> +++ head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c Wed Sep 16 14:26:28 2015 (r287861) A> @@ -1333,7 +1333,7 @@ ipoib_output(struct ifnet *ifp, struct m A> else if (m->m_flags & M_MCAST) A> ipv6_ib_mc_map(&((struct sockaddr_in6 *)dst)->sin6_addr, ifp->if_broadcastaddr, edst); A> else A> - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); A> + error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL); A> if (error) A> return error; A> type = htons(ETHERTYPE_IPV6); A> -- Totus tuus, Glebius.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150916165616.GP1023>