diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-11-27 23:06:25 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-11-27 23:06:25 +0000 |
commit | 95c680b9a37dc9e1e605f6d9ce346203c0d1aac4 (patch) | |
tree | b985650fb7687bf95b809dfda2d768fed6e073d2 /sys | |
parent | 09e88907610d93e098d017e8e705eed832e10d21 (diff) | |
download | FreeBSD-src-95c680b9a37dc9e1e605f6d9ce346203c0d1aac4.zip FreeBSD-src-95c680b9a37dc9e1e605f6d9ce346203c0d1aac4.tar.gz |
Do not return unlocked/unreferenced lle in arpresolve/nd6_storelladdr -
return lle flags IFF needed.
Do not pass rte to arpresolve - pass is_gateway flag instead.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_arcsubr.c | 13 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 20 | ||||
-rw-r--r-- | sys/net/if_fddisubr.c | 16 | ||||
-rw-r--r-- | sys/net/if_fwsubr.c | 12 | ||||
-rw-r--r-- | sys/net/if_iso88025subr.c | 13 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 19 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 5 | ||||
-rw-r--r-- | sys/netinet/toecore.c | 5 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 8 | ||||
-rw-r--r-- | sys/netinet6/nd6.h | 2 | ||||
-rw-r--r-- | sys/ofed/drivers/infiniband/core/addr.c | 10 | ||||
-rw-r--r-- | sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 |
12 files changed, 72 insertions, 59 deletions
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c index 617f9ee..d9a6cab 100644 --- a/sys/net/if_arcsubr.c +++ b/sys/net/if_arcsubr.c @@ -103,9 +103,7 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, u_int8_t atype, adst; int loop_copy = 0; int isphds; -#if defined(INET) || defined(INET6) - struct llentry *lle; -#endif + int is_gw; if (!((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))) @@ -125,8 +123,11 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, else if (ifp->if_flags & IFF_NOARP) adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF; else { - error = arpresolve(ifp, ro ? ro->ro_rt : NULL, - m, dst, &adst, &lle); + is_gw = 0; + if (ro != NULL && ro->ro_rt != NULL && + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; + error = arpresolve(ifp, is_gw, m, dst, &adst, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); } @@ -164,7 +165,7 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, #endif #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, m, dst, (u_char *)&adst, &lle); + error = nd6_storelladdr(ifp, m, dst, (u_char *)&adst, NULL); if (error) return (error); atype = ARCTYPE_INET6; diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index c6f2cc6..2709c5e 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -154,11 +154,18 @@ ether_output(struct ifnet *ifp, struct mbuf *m, struct pf_mtag *t; int loop_copy = 1; int hlen; /* link layer header length */ + int is_gw = 0; + uint32_t pflags = 0; if (ro != NULL) { - if (!(m->m_flags & (M_BCAST | M_MCAST))) + if (!(m->m_flags & (M_BCAST | M_MCAST))) { lle = ro->ro_lle; + if (lle != NULL) + pflags = lle->la_flags; + } rt0 = ro->ro_rt; + if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; } #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -177,10 +184,10 @@ ether_output(struct ifnet *ifp, struct mbuf *m, switch (dst->sa_family) { #ifdef INET case AF_INET: - if (lle != NULL && (lle->la_flags & LLE_VALID)) + if (lle != NULL && (pflags & LLE_VALID) != 0) memcpy(edst, &lle->ll_addr.mac16, sizeof(edst)); else - error = arpresolve(ifp, rt0, m, dst, edst, &lle); + error = arpresolve(ifp, is_gw, m, dst, edst, &pflags); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -215,10 +222,11 @@ ether_output(struct ifnet *ifp, struct mbuf *m, #endif #ifdef INET6 case AF_INET6: - if (lle != NULL && (lle->la_flags & LLE_VALID)) + if (lle != NULL && (pflags & LLE_VALID)) memcpy(edst, &lle->ll_addr.mac16, sizeof(edst)); else - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, &lle); + error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, + &pflags); if (error) return error; type = htons(ETHERTYPE_IPV6); @@ -241,7 +249,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m, senderr(EAFNOSUPPORT); } - if (lle != NULL && (lle->la_flags & LLE_IFADDR)) { + if ((pflags & LLE_IFADDR) != 0) { update_mbuf_csumflags(m, m); return (if_simloop(ifp, m, dst->sa_family, 0)); } diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index da54ebf..91b26e5 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -101,9 +101,7 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, int loop_copy = 0, error = 0, hdrcmplt = 0; u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN]; struct fddi_header *fh; -#if defined(INET) || defined(INET6) - struct llentry *lle; -#endif + int is_gw; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -121,11 +119,11 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, switch (dst->sa_family) { #ifdef INET case AF_INET: { - struct rtentry *rt0 = NULL; - - if (ro != NULL) - rt0 = ro->ro_rt; - error = arpresolve(ifp, rt0, m, dst, edst, &lle); + is_gw = 0; + if (ro != NULL && ro->ro_rt != NULL && + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; + error = arpresolve(ifp, is_gw, m, dst, edst, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -161,7 +159,7 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, #endif /* INET */ #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, &lle); + error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); if (error) return (error); /* Something bad happened */ type = htons(ETHERTYPE_IPV6); diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c index 39e9cf9..fd4851e 100644 --- a/sys/net/if_fwsubr.c +++ b/sys/net/if_fwsubr.c @@ -89,9 +89,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct mbuf *mtail; int unicast, dgl, foff; static int next_dgl; -#if defined(INET) || defined(INET6) - struct llentry *lle; -#endif + int is_gw; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -140,7 +138,11 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, * doesn't fit into the arp model. */ if (unicast) { - error = arpresolve(ifp, ro ? ro->ro_rt : NULL, m, dst, (u_char *) destfw, &lle); + is_gw = 0; + if (ro != NULL && ro->ro_rt != NULL && + (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; + error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); } @@ -170,7 +172,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, case AF_INET6: if (unicast) { error = nd6_storelladdr(fc->fc_ifp, m, dst, - (u_char *) destfw, &lle); + (u_char *) destfw, NULL); if (error) return (error); } diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c index 8e55e8b..727df37 100644 --- a/sys/net/if_iso88025subr.c +++ b/sys/net/if_iso88025subr.c @@ -212,12 +212,13 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct iso88025_header gen_th; struct sockaddr_dl *sdl = NULL; struct rtentry *rt0 = NULL; -#if defined(INET) || defined(INET6) - struct llentry *lle; -#endif + int is_gw = 0; - if (ro != NULL) + if (ro != NULL) { rt0 = ro->ro_rt; + if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; + } #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -257,7 +258,7 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, switch (dst->sa_family) { #ifdef INET case AF_INET: - error = arpresolve(ifp, rt0, m, dst, edst, &lle); + error = arpresolve(ifp, is_gw, m, dst, edst, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); snap_type = ETHERTYPE_IP; @@ -292,7 +293,7 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, #endif /* INET */ #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, &lle); + error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); if (error) return (error); snap_type = ETHERTYPE_IPV6; diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index d5d9798..f1d0656 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -286,19 +286,20 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip, * Resolve an IP address into an ethernet address. * On input: * ifp is the interface we use - * rt0 is the route to the final destination (possibly useless) + * is_gw != if @dst represents gateway to some destination * m is the mbuf. May be NULL if we don't have a packet. * dst is the next hop, * desten is where we want the address. + * flags returns lle entry flags. * - * On success, desten is filled in and the function returns 0; + * On success, desten and flags are filled in and the function returns 0; * If the packet must be held pending resolution, we return EWOULDBLOCK * On other errors, we return the corresponding error code. * Note that m_freem() handles NULL. */ int -arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, - const struct sockaddr *dst, u_char *desten, struct llentry **lle) +arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m, + const struct sockaddr *dst, u_char *desten, uint32_t *pflags) { struct llentry *la = 0; u_int flags = 0; @@ -306,7 +307,9 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, struct mbuf *next = NULL; int error, renew; - *lle = NULL; + if (pflags != NULL) + *pflags = 0; + if (m != NULL) { if (m->m_flags & M_BCAST) { /* broadcast */ @@ -354,7 +357,8 @@ retry: la->la_preempt--; } - *lle = la; + if (pflags != NULL) + *pflags = la->la_flags; error = 0; goto done; } @@ -412,8 +416,7 @@ retry: if (la->la_asked < V_arp_maxtries) error = EWOULDBLOCK; /* First request. */ else - error = rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) ? - EHOSTUNREACH : EHOSTDOWN; + error = is_gw != 0 ? EHOSTUNREACH : EHOSTDOWN; if (renew) { int canceled; diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index fbd0a1a..39fc386 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -112,11 +112,10 @@ struct sockaddr_inarp { extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN]; extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN]; -struct llentry; struct ifaddr; -int arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m, - const struct sockaddr *dst, u_char *desten, struct llentry **lle); +int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m, + const struct sockaddr *dst, u_char *desten, uint32_t *pflags); void arprequest(struct ifnet *, const struct in_addr *, const struct in_addr *, u_char *); void arp_ifinit(struct ifnet *, struct ifaddr *); diff --git a/sys/netinet/toecore.c b/sys/netinet/toecore.c index 1ab6c73..1021475 100644 --- a/sys/netinet/toecore.c +++ b/sys/netinet/toecore.c @@ -516,15 +516,12 @@ int toe_l2_resolve(struct toedev *tod, struct ifnet *ifp, struct sockaddr *sa, uint8_t *lladdr, uint16_t *vtag) { -#ifdef INET - struct llentry *lle; -#endif int rc; switch (sa->sa_family) { #ifdef INET case AF_INET: - rc = arpresolve(ifp, NULL, NULL, sa, lladdr, &lle); + rc = arpresolve(ifp, 0, NULL, sa, lladdr, NULL); break; #endif #ifdef INET6 diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index b2b615c..5e1f25f 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2278,11 +2278,12 @@ nd6_rem_ifa_lle(struct in6_ifaddr *ia) */ int nd6_storelladdr(struct ifnet *ifp, struct mbuf *m, - const struct sockaddr *dst, u_char *desten, struct llentry **lle) + const struct sockaddr *dst, u_char *desten, uint32_t *pflags) { struct llentry *ln; - *lle = NULL; + if (pflags != NULL) + *pflags = 0; IF_AFDATA_UNLOCK_ASSERT(ifp); if (m != NULL && m->m_flags & M_MCAST) { int i; @@ -2334,7 +2335,8 @@ nd6_storelladdr(struct ifnet *ifp, struct mbuf *m, } bcopy(&ln->ll_addr, desten, ifp->if_addrlen); - *lle = ln; + if (pflags != NULL) + *pflags = ln->la_flags; LLE_RUNLOCK(ln); /* * A *small* use after free race exists here diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 358f4ec..17db618 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -418,7 +418,7 @@ int nd6_need_cache(struct ifnet *); int nd6_add_ifa_lle(struct in6_ifaddr *); void nd6_rem_ifa_lle(struct in6_ifaddr *); int nd6_storelladdr(struct ifnet *, struct mbuf *, - const struct sockaddr *, u_char *, struct llentry **); + const struct sockaddr *, u_char *, uint32_t *); /* nd6_nbr.c */ void nd6_na_input(struct mbuf *, int, int); diff --git a/sys/ofed/drivers/infiniband/core/addr.c b/sys/ofed/drivers/infiniband/core/addr.c index f608244..c3d5b4f 100644 --- a/sys/ofed/drivers/infiniband/core/addr.c +++ b/sys/ofed/drivers/infiniband/core/addr.c @@ -347,14 +347,12 @@ static int addr_resolve(struct sockaddr *src_in, struct sockaddr_in6 *sin6; struct ifaddr *ifa; struct ifnet *ifp; -#if defined(INET) || defined(INET6) - struct llentry *lle; -#endif struct rtentry *rte; in_port_t port; u_char edst[MAX_ADDR_LEN]; int multi; int bcast; + int is_gw = 0; int error = 0; /* @@ -430,6 +428,8 @@ static int addr_resolve(struct sockaddr *src_in, RTFREE_LOCKED(rte); return -EHOSTUNREACH; } + if (rte->rt_flags & RTF_GATEWAY) + is_gw = 1; /* * If it's not multicast or broadcast and the route doesn't match the * requested interface return unreachable. Otherwise fetch the @@ -467,12 +467,12 @@ mcast: switch (dst_in->sa_family) { #ifdef INET case AF_INET: - error = arpresolve(ifp, rte, NULL, dst_in, edst, &lle); + error = arpresolve(ifp, is_gw, NULL, dst_in, edst, NULL); break; #endif #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, NULL, dst_in, (u_char *)edst, &lle); + error = nd6_storelladdr(ifp, NULL, dst_in, (u_char *)edst,NULL); break; #endif default: diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5cd3441..b3afc210 100644 --- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1259,13 +1259,15 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m, struct llentry *lle = NULL; struct rtentry *rt0 = NULL; struct ipoib_header *eh; - int error = 0; + int error = 0, is_gw = 0; short type; if (ro != NULL) { if (!(m->m_flags & (M_BCAST | M_MCAST))) lle = ro->ro_lle; rt0 = ro->ro_rt; + if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0) + is_gw = 1; } #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -1292,7 +1294,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m, else if (m->m_flags & M_MCAST) ip_ib_mc_map(((struct sockaddr_in *)dst)->sin_addr.s_addr, ifp->if_broadcastaddr, edst); else - error = arpresolve(ifp, rt0, m, dst, edst, &lle); + error = arpresolve(ifp, is_gw, m, dst, edst, NULL); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -1330,7 +1332,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m, else if (m->m_flags & M_MCAST) ipv6_ib_mc_map(&((struct sockaddr_in6 *)dst)->sin6_addr, ifp->if_broadcastaddr, edst); else - error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, &lle); + error = nd6_storelladdr(ifp, m, dst, (u_char *)edst, NULL); if (error) return error; type = htons(ETHERTYPE_IPV6); |