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