svn commit: r186000 - in projects/arpv2_merge_1/sys: net netinet

Kip Macy kmacy at FreeBSD.org
Fri Dec 12 13:45:11 PST 2008


Author: kmacy
Date: Fri Dec 12 21:45:10 2008
New Revision: 186000
URL: http://svn.freebsd.org/changeset/base/186000

Log:
  We no longer automatically create a host route to the gateway for storing its L2
  information. This changes remove rt_gwroute from rtentry and the corresponding
  validation function rt_check.

Modified:
  projects/arpv2_merge_1/sys/net/if_atmsubr.c
  projects/arpv2_merge_1/sys/net/if_fwsubr.c
  projects/arpv2_merge_1/sys/net/if_iso88025subr.c
  projects/arpv2_merge_1/sys/net/route.c
  projects/arpv2_merge_1/sys/net/route.h
  projects/arpv2_merge_1/sys/netinet/if_ether.c

Modified: projects/arpv2_merge_1/sys/net/if_atmsubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_atmsubr.c	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/net/if_atmsubr.c	Fri Dec 12 21:45:10 2008	(r186000)
@@ -153,22 +153,11 @@ atm_output(struct ifnet *ifp, struct mbu
 		case AF_INET:
 		case AF_INET6:
 		{
-			struct rtentry *rt = NULL;
-			/*  
-			 * check route
-			 */
-			if (rt0 != NULL) {
-				error = rt_check(&rt, &rt0, dst);
-				if (error)
-					goto bad;
-				RT_UNLOCK(rt);
-			}
-
 			if (dst->sa_family == AF_INET6)
 			        etype = ETHERTYPE_IPV6;
 			else
 			        etype = ETHERTYPE_IP;
-			if (!atmresolve(rt, m, dst, &atmdst)) {
+			if (!atmresolve(rt0, m, dst, &atmdst)) {
 				m = NULL; 
 				/* XXX: atmresolve already free'd it */
 				senderr(EHOSTUNREACH);

Modified: projects/arpv2_merge_1/sys/net/if_fwsubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_fwsubr.c	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/net/if_fwsubr.c	Fri Dec 12 21:45:10 2008	(r186000)
@@ -81,7 +81,6 @@ firewire_output(struct ifnet *ifp, struc
 {
 	struct fw_com *fc = IFP2FWC(ifp);
 	int error, type;
-	struct rtentry *rt = NULL;
 	struct m_tag *mtag;
 	union fw_encap *enc;
 	struct fw_hwaddr *destfw;
@@ -104,13 +103,6 @@ firewire_output(struct ifnet *ifp, struc
 		goto bad;
 	}
 
-	if (rt0 != NULL) {
-		error = rt_check(&rt, &rt0, dst);
-		if (error)
-			goto bad;
-		RT_UNLOCK(rt);
-	}
-
 	/*
 	 * For unicast, we make a tag to store the lladdr of the
 	 * destination. This might not be the first time we have seen
@@ -146,7 +138,7 @@ firewire_output(struct ifnet *ifp, struc
 		 * doesn't fit into the arp model.
 		 */
 		if (unicast) {
-			error = arpresolve(ifp, rt, m, dst, (u_char *) destfw, &lle);
+			error = arpresolve(ifp, rt0, m, dst, (u_char *) destfw, &lle);
 			if (error)
 				return (error == EWOULDBLOCK ? 0 : error);
 		}
@@ -175,7 +167,7 @@ firewire_output(struct ifnet *ifp, struc
 #ifdef INET6
 	case AF_INET6:
 		if (unicast) {
-			error = nd6_storelladdr(fc->fc_ifp, rt, m, dst,
+			error = nd6_storelladdr(fc->fc_ifp, rt0, m, dst,
 			    (u_char *) destfw, &lle);
 			if (error)
 				return (error);

Modified: projects/arpv2_merge_1/sys/net/if_iso88025subr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_iso88025subr.c	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/net/if_iso88025subr.c	Fri Dec 12 21:45:10 2008	(r186000)
@@ -244,7 +244,6 @@ iso88025_output(ifp, m, dst, rt0)
 	struct iso88025_header *th;
 	struct iso88025_header gen_th;
 	struct sockaddr_dl *sdl = NULL;
-	struct rtentry *rt = NULL;
 	struct llentry *lle;
 
 #ifdef MAC
@@ -262,14 +261,8 @@ iso88025_output(ifp, m, dst, rt0)
 
 	/* Calculate routing info length based on arp table entry */
 	/* XXX any better way to do this ? */
-	if (rt0 != NULL) {
-		error = rt_check(&rt, &rt0, dst);
-		if (error)
-			goto bad;
-		RT_UNLOCK(rt);
-	}
 
-	if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway))
+	if (rt0 && (sdl = (struct sockaddr_dl *)rt0->rt_gateway))
 		if (SDL_ISO88025(sdl)->trld_rcf != 0)
 			rif_len = TR_RCF_RIFLEN(SDL_ISO88025(sdl)->trld_rcf);
 

Modified: projects/arpv2_merge_1/sys/net/route.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/route.c	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/net/route.c	Fri Dec 12 21:45:10 2008	(r186000)
@@ -783,16 +783,6 @@ rtexpunge(struct rtentry *rt)
 	rt->rt_flags &= ~RTF_UP;
 
 	/*
-	 * Remove any external references we may have.
-	 * This might result in another rtentry being freed if
-	 * we held its last reference.
-	 */
-	if (rt->rt_gwroute) {
-		RTFREE(rt->rt_gwroute);
-		rt->rt_gwroute = NULL;
-	}
-
-	/*
 	 * Give the protocol a chance to keep things in sync.
 	 */
 	if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) {
@@ -934,16 +924,6 @@ normal_rtdel:
 		rt->rt_flags &= ~RTF_UP;
 
 		/*
-		 * Remove any external references we may have.
-		 * This might result in another rtentry being freed if
-		 * we held its last reference.
-		 */
-		if (rt->rt_gwroute) {
-			RTFREE(rt->rt_gwroute);
-			rt->rt_gwroute = NULL;
-		}
-
-		/*
 		 * give the protocol a chance to keep things in sync.
 		 */
 		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
@@ -994,7 +974,7 @@ deldone:
 		rt->rt_fibnum = fibnum;
 		/*
 		 * Add the gateway. Possibly re-malloc-ing the storage for it
-		 * also add the rt_gwroute if possible.
+		 * 
 		 */
 		RT_LOCK(rt);
 		if ((error = rt_setgate(rt, dst, gateway)) != 0) {
@@ -1029,8 +1009,6 @@ deldone:
 		/* do not permit exactly the same dst/mask/gw pair */
 		if (rn_mpath_capable(rnh) &&
 			rt_mpath_conflict(rnh, rt, netmask)) {
-			if (rt->rt_gwroute)
-				RTFREE(rt->rt_gwroute);
 			if (rt->rt_ifa) {
 				IFAFREE(rt->rt_ifa);
 			}
@@ -1048,8 +1026,6 @@ deldone:
 		 * then un-make it (this should be a function)
 		 */
 		if (rn == NULL) {
-			if (rt->rt_gwroute)
-				RTFREE(rt->rt_gwroute);
 			if (rt->rt_ifa)
 				IFAFREE(rt->rt_ifa);
 			Free(rt_key(rt));
@@ -1101,48 +1077,10 @@ rt_setgate(struct rtentry *rt, struct so
 	    V_rt_tables[rt->rt_fibnum][dst->sa_family];
 	int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
 
-again:
 	RT_LOCK_ASSERT(rt);
 	RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
 	
 	/*
-	 * Cloning loop avoidance in case of bad configuration.
-	 */
-	if (rt->rt_flags & RTF_GATEWAY) {
-		struct rtentry *gwrt;
-
-		RT_UNLOCK(rt);		/* XXX workaround LOR */
-		gwrt = rtalloc1_fib(gate, 1, RTF_RNH_LOCKED, rt->rt_fibnum);
-		if (gwrt == rt) {
-			RT_REMREF(rt);
-			return (EADDRINUSE); /* failure */
-		}
-		/*
-		 * Try to reacquire the lock on rt, and if it fails,
-		 * clean state and restart from scratch.
-		 */
-		if (!RT_TRYLOCK(rt)) {
-			RTFREE_LOCKED(gwrt);
-			RT_LOCK(rt);
-			goto again;
-		}
-		/*
-		 * If there is already a gwroute, then drop it. If we
-		 * are asked to replace route with itself, then do
-		 * not leak its refcounter.
-		 */
-		if (rt->rt_gwroute != NULL) {
-			if (rt->rt_gwroute == gwrt) {
-				RT_REMREF(rt->rt_gwroute);
-			} else
-				RTFREE(rt->rt_gwroute);
-		}
-
-		if ((rt->rt_gwroute = gwrt) != NULL)
-			RT_UNLOCK(rt->rt_gwroute);
-	}
-
-	/*
 	 * Prepare to store the gateway in rt->rt_gateway.
 	 * Both dst and gateway are stored one after the other in the same
 	 * malloc'd chunk. If we have room, we can reuse the old buffer,
@@ -1426,147 +1364,5 @@ rtinit(struct ifaddr *ifa, int cmd, int 
 	return (rtinit1(ifa, cmd, flags, fib));
 }
 
-/*
- * rt_check() is invoked on each layer 2 output path, prior to
- * encapsulating outbound packets.
- *
- * The function is mostly used to find a routing entry for the gateway,
- * which in some protocol families could also point to the link-level
- * address for the gateway itself (the side effect of revalidating the
- * route to the destination is rather pointless at this stage, we did it
- * already a moment before in the pr_output() routine to locate the ifp
- * and gateway to use).
- *
- * When we remove the layer-3 to layer-2 mapping tables from the
- * routing table, this function can be removed.
- *
- * === On input ===
- *   *dst is the address of the NEXT HOP (which coincides with the
- *	final destination if directly reachable);
- *   *lrt0 points to the cached route to the final destination;
- *   *lrt is not meaningful;
- *	(*lrt0 has no ref held on it by us so REMREF is not needed.
- *	Refs only account for major structural references and not usages,
- * 	which is actually a bit of a problem.)
- *
- * === Operation ===
- * If the route is marked down try to find a new route.  If the route
- * to the gateway is gone, try to setup a new route.  Otherwise,
- * if the route is marked for packets to be rejected, enforce that.
- * Note that rtalloc returns an rtentry with an extra REF that we may
- * need to lose.
- *
- * === On return ===
- *   *dst is unchanged;
- *   *lrt0 points to the (possibly new) route to the final destination
- *   *lrt points to the route to the next hop   [LOCKED]
- *
- * Their values are meaningful ONLY if no error is returned.
- *
- * To follow this you have to remember that:
- * RT_REMREF reduces the reference count by 1 but doesn't check it for 0 (!)
- * RTFREE_LOCKED includes an RT_REMREF (or an rtfree if refs == 1)
- *    and an RT_UNLOCK
- * RTFREE does an RT_LOCK and an RTFREE_LOCKED
- * The gwroute pointer counts as a reference on the rtentry to which it points.
- * so when we add it we use the ref that rtalloc gives us and when we lose it
- * we need to remove the reference.
- * RT_TEMP_UNLOCK does an RT_ADDREF before freeing the lock, and
- * RT_RELOCK locks it (it can't have gone away due to the ref) and
- * drops the ref, possibly freeing it and zeroing the pointer if
- * the ref goes to 0 (unlocking in the process).
- */
-int
-rt_check(struct rtentry **lrt, struct rtentry **lrt0, struct sockaddr *dst)
-{
-	struct rtentry *rt;
-	struct rtentry *rt0;
-	u_int fibnum;
-
-	KASSERT(*lrt0 != NULL, ("rt_check"));
-	rt0 = *lrt0;
-	rt = NULL;
-	fibnum = rt0->rt_fibnum;
-
-	/* NB: the locking here is tortuous... */
-	RT_LOCK(rt0);
-retry:
-	if (rt0 && (rt0->rt_flags & RTF_UP) == 0) {
-		/* Current rt0 is useless, try get a replacement. */
-		RT_UNLOCK(rt0);
-		rt0 = NULL;
-	}
-	if (rt0 == NULL) {
-		rt0 = rtalloc1_fib(dst, 1, 0UL, fibnum);
-		if (rt0 == NULL) {
-			return (EHOSTUNREACH);
-		}
-		RT_REMREF(rt0); /* don't need the reference. */
-	}
-
-	if (rt0->rt_flags & RTF_GATEWAY) {
-		if ((rt = rt0->rt_gwroute) != NULL) {
-			RT_LOCK(rt);		/* NB: gwroute */
-			if ((rt->rt_flags & RTF_UP) == 0) {
-				/* gw route is dud. ignore/lose it */
-				RTFREE_LOCKED(rt); /* unref (&unlock) gwroute */
-				rt = rt0->rt_gwroute = NULL;
-			}
-		}
-		
-		if (rt == NULL) {  /* NOT AN ELSE CLAUSE */
-			RT_TEMP_UNLOCK(rt0); /* MUST return to undo this */
-			rt = rtalloc1_fib(rt0->rt_gateway, 1, 0UL, fibnum);
-			if ((rt == rt0) || (rt == NULL)) {
-				/* the best we can do is not good enough */
-				if (rt) {
-					RT_REMREF(rt); /* assumes ref > 0 */
-					RT_UNLOCK(rt);
-				}
-				RTFREE(rt0); /* lock, unref, (unlock) */
-				return (ENETUNREACH);
-			}
-			/*
-			 * Relock it and lose the added reference.
-			 * All sorts of things could have happenned while we
-			 * had no lock on it, so check for them.
-			 */
-			RT_RELOCK(rt0);
-			if (rt0 == NULL || ((rt0->rt_flags & RTF_UP) == 0))
-				/* Ru-roh.. what we had is no longer any good */
-				goto retry;
-			/* 
-			 * While we were away, someone replaced the gateway.
-			 * Since a reference count is involved we can't just
-			 * overwrite it.
-			 */
-			if (rt0->rt_gwroute) {
-				if (rt0->rt_gwroute != rt) {
-					RTFREE_LOCKED(rt);
-					goto retry;
-				}
-			} else {
-				rt0->rt_gwroute = rt;
-			}
-		}
-		RT_LOCK_ASSERT(rt);
-		RT_UNLOCK(rt0);
-	} else {
-		/* think of rt as having the lock from now on.. */
-		rt = rt0;
-	}
-	/* XXX why are we inspecting rmx_expire? */
-	if ((rt->rt_flags & RTF_REJECT) &&
-	    (rt->rt_rmx.rmx_expire == 0 ||
-	    time_uptime < rt->rt_rmx.rmx_expire)) {
-		RT_UNLOCK(rt);
-		return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
-	}
-
-	*lrt = rt;
-	*lrt0 = rt0;
-	return (0);
-}
-
 /* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
 SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);

Modified: projects/arpv2_merge_1/sys/net/route.h
==============================================================================
--- projects/arpv2_merge_1/sys/net/route.h	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/net/route.h	Fri Dec 12 21:45:10 2008	(r186000)
@@ -140,7 +140,6 @@ struct rtentry {
 	struct	ifnet *rt_ifp;		/* the answer: interface to use */
 	struct	ifaddr *rt_ifa;		/* the answer: interface address to use */
 	struct	rt_metrics_lite rt_rmx;	/* metrics used by rx'ing protocols */
-	struct	rtentry *rt_gwroute;	/* implied entry for gatewayed routes */
 	u_int	rt_fibnum;		/* which FIB */
 #ifdef _KERNEL
 	/* XXX ugly, user apps use this definition but don't have a mtx def */

Modified: projects/arpv2_merge_1/sys/netinet/if_ether.c
==============================================================================
--- projects/arpv2_merge_1/sys/netinet/if_ether.c	Fri Dec 12 20:29:34 2008	(r185999)
+++ projects/arpv2_merge_1/sys/netinet/if_ether.c	Fri Dec 12 21:45:10 2008	(r186000)
@@ -276,7 +276,9 @@ arpresolve(struct ifnet *ifp, struct rte
 	 * XXX if caller is required to hold lock, assert it
 	 */
 retry:
+	IF_AFDATA_LOCK(ifp);	
 	la = lla_lookup(LLTABLE(ifp), flags, dst);
+	IF_AFDATA_UNLOCK(ifp);	
 	if (la == NULL) {
 		if (flags & LLE_CREATE)
 			log(LOG_DEBUG,


More information about the svn-src-projects mailing list