Date: Fri, 12 Dec 2008 21:45:10 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r186000 - in projects/arpv2_merge_1/sys: net netinet Message-ID: <200812122145.mBCLjAgw009326@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812122145.mBCLjAgw009326>