svn commit: r275196 - in head/sys: net netinet netinet6 ofed/drivers/infiniband/core ofed/drivers/infiniband/ulp/ipoib

Alexander V. Chernikov melifaro at FreeBSD.org
Thu Nov 27 23:06:29 UTC 2014


Author: melifaro
Date: Thu Nov 27 23:06:25 2014
New Revision: 275196
URL: https://svnweb.freebsd.org/changeset/base/275196

Log:
  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.

Modified:
  head/sys/net/if_arcsubr.c
  head/sys/net/if_ethersubr.c
  head/sys/net/if_fddisubr.c
  head/sys/net/if_fwsubr.c
  head/sys/net/if_iso88025subr.c
  head/sys/netinet/if_ether.c
  head/sys/netinet/if_ether.h
  head/sys/netinet/toecore.c
  head/sys/netinet6/nd6.c
  head/sys/netinet6/nd6.h
  head/sys/ofed/drivers/infiniband/core/addr.c
  head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c

Modified: head/sys/net/if_arcsubr.c
==============================================================================
--- head/sys/net/if_arcsubr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/net/if_arcsubr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -103,9 +103,7 @@ arc_output(struct ifnet *ifp, struct mbu
 	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 mbu
 		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 mbu
 #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;

Modified: head/sys/net/if_ethersubr.c
==============================================================================
--- head/sys/net/if_ethersubr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/net/if_ethersubr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -154,11 +154,18 @@ ether_output(struct ifnet *ifp, struct 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 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 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 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));
 	}

Modified: head/sys/net/if_fddisubr.c
==============================================================================
--- head/sys/net/if_fddisubr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/net/if_fddisubr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -101,9 +101,7 @@ fddi_output(struct ifnet *ifp, struct mb
 	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 mb
 	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 mb
 #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);

Modified: head/sys/net/if_fwsubr.c
==============================================================================
--- head/sys/net/if_fwsubr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/net/if_fwsubr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -89,9 +89,7 @@ firewire_output(struct ifnet *ifp, struc
 	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, struc
 		 * 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, struc
 	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);
 		}

Modified: head/sys/net/if_iso88025subr.c
==============================================================================
--- head/sys/net/if_iso88025subr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/net/if_iso88025subr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -212,12 +212,13 @@ iso88025_output(struct ifnet *ifp, struc
 	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, struc
 	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, struc
 #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;

Modified: head/sys/netinet/if_ether.c
==============================================================================
--- head/sys/netinet/if_ether.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/netinet/if_ether.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -286,19 +286,20 @@ arprequest(struct ifnet *ifp, const stru
  * 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 rte
 	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;

Modified: head/sys/netinet/if_ether.h
==============================================================================
--- head/sys/netinet/if_ether.h	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/netinet/if_ether.h	Thu Nov 27 23:06:25 2014	(r275196)
@@ -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 *);

Modified: head/sys/netinet/toecore.c
==============================================================================
--- head/sys/netinet/toecore.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/netinet/toecore.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -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

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/netinet6/nd6.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -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, struc
 	}
 
 	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

Modified: head/sys/netinet6/nd6.h
==============================================================================
--- head/sys/netinet6/nd6.h	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/netinet6/nd6.h	Thu Nov 27 23:06:25 2014	(r275196)
@@ -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);

Modified: head/sys/ofed/drivers/infiniband/core/addr.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/addr.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/ofed/drivers/infiniband/core/addr.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -347,14 +347,12 @@ static int addr_resolve(struct sockaddr 
 	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 
 			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:

Modified: head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c	Thu Nov 27 21:29:19 2014	(r275195)
+++ head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c	Thu Nov 27 23:06:25 2014	(r275196)
@@ -1259,13 +1259,15 @@ ipoib_output(struct ifnet *ifp, struct 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 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 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);


More information about the svn-src-head mailing list