Date: Wed, 31 Dec 2008 03:13:05 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r186625 - user/kmacy/HEAD_fast_net/sys/net Message-ID: <200812310313.mBV3D5ed013238@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Wed Dec 31 03:13:05 2008 New Revision: 186625 URL: http://svn.freebsd.org/changeset/base/186625 Log: import kernel support for route shutdown Modified: user/kmacy/HEAD_fast_net/sys/net/radix_mpath.c user/kmacy/HEAD_fast_net/sys/net/route.c user/kmacy/HEAD_fast_net/sys/net/route.h Modified: user/kmacy/HEAD_fast_net/sys/net/radix_mpath.c ============================================================================== --- user/kmacy/HEAD_fast_net/sys/net/radix_mpath.c Wed Dec 31 03:02:59 2008 (r186624) +++ user/kmacy/HEAD_fast_net/sys/net/radix_mpath.c Wed Dec 31 03:13:05 2008 (r186625) @@ -81,11 +81,15 @@ u_int32_t rn_mpath_count(struct radix_node *rn) { u_int32_t i; - + struct rtentry *rt; + i = 1; - while ((rn = rn_mpath_next(rn)) != NULL) - i++; - return i; + while ((rn = rn_mpath_next(rn)) != NULL) { + rt = (struct rtentry *)rn; + if ((rt->rt_flags & RTF_SHUTDOWN) == 0) + i++; + } + return (i); } struct rtentry * @@ -260,7 +264,8 @@ rtalloc_mpath_fib(struct route *ro, u_in { struct radix_node *rn0, *rn; u_int32_t n; - + struct rtentry *rt; + /* * XXX we don't attempt to lookup cached route again; what should * be done for sendto(3) case? @@ -285,6 +290,11 @@ rtalloc_mpath_fib(struct route *ro, u_in hash += hashjitter; hash %= n; while (hash-- > 0 && rn) { + rt = (struct rtentry *)rn; + if (rt->rt_flags & RTF_SHUTDOWN) { + hash++; + continue; + } /* stay within the multipath routes */ if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask) break; Modified: user/kmacy/HEAD_fast_net/sys/net/route.c ============================================================================== --- user/kmacy/HEAD_fast_net/sys/net/route.c Wed Dec 31 03:02:59 2008 (r186624) +++ user/kmacy/HEAD_fast_net/sys/net/route.c Wed Dec 31 03:13:05 2008 (r186625) @@ -803,6 +803,98 @@ bad: return (error); } +#ifdef RADIX_MPATH +static int +rn_mpath_delete(int req, struct rt_addrinfo *info, + struct radix_node_head *rnh, struct rtentry **ret_nrt) +{ + /* + * if we got multipath routes, we require users to specify + * a matching RTAX_GATEWAY. + */ + struct rtentry *rto = NULL; + int error = 0; + + rn = rnh->rnh_matchaddr(dst, rnh); + if (rn == NULL) + return (ESRCH); + rto = rt = RNTORT(rn); + rt = rt_mpath_matchgate(rt, gateway); + if (!rt) + return (ESRCH); + /* + * this is the first entry in the chain + */ + if (rto == rt) { + rn = rn_mpath_next((struct radix_node *)rt); + /* + * there is another entry, now it's active + */ + if (rn) { + rto = RNTORT(rn); + RT_LOCK(rto); + rto->rt_flags |= RTF_UP; + RT_UNLOCK(rto); + } else if (rt->rt_flags & RTF_GATEWAY) { + /* + * For gateway routes, we need to + * make sure that we we are deleting + * the correct gateway. + * rt_mpath_matchgate() does not + * check the case when there is only + * one route in the chain. + */ + if (gateway && + (rt->rt_gateway->sa_len != gateway->sa_len || + memcmp(rt->rt_gateway, gateway, gateway->sa_len))) + error = ESRCH; + goto done; + } + /* + * use the normal delete code to remove + * the first entry + */ + error = ENOENT; + goto done; + } + + /* + * if the entry is 2nd and on up + */ + if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt)) + panic ("rtrequest1: rt_mpath_deldup"); + RT_LOCK(rt); + RT_ADDREF(rt); + if (req == RTM_DELETE) { + rt->rt_flags &= ~RTF_UP; + /* + * One more rtentry floating around that is not + * linked to the routing table. rttrash will be decremented + * when RTFREE(rt) is eventually called. + */ + V_rttrash++; + + } else if (req == RTM_SHUTDOWN) + rt->rt_flags |= RTF_SHUTDOWN; + else + panic("unrecognized request %d", req); + + + /* + * If the caller wants it, then it can have it, + * but it's up to it to free the rtentry as we won't be + * doing it. + */ + if (ret_nrt) { + *ret_nrt = rt; + RT_UNLOCK(rt); + } else + RTFREE_LOCKED(rt); +done: + return (error); +} +#endif + int rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, u_int fibnum) @@ -841,65 +933,16 @@ rtrequest1_fib(int req, struct rt_addrin switch (req) { case RTM_DELETE: #ifdef RADIX_MPATH - /* - * if we got multipath routes, we require users to specify - * a matching RTAX_GATEWAY. - */ + case RTM_SHUTDOWN: if (rn_mpath_capable(rnh)) { - struct rtentry *rto = NULL; - - rn = rnh->rnh_matchaddr(dst, rnh); - if (rn == NULL) - senderr(ESRCH); - rto = rt = RNTORT(rn); - rt = rt_mpath_matchgate(rt, gateway); - if (!rt) - senderr(ESRCH); - /* - * this is the first entry in the chain - */ - if (rto == rt) { - rn = rn_mpath_next((struct radix_node *)rt); - /* - * there is another entry, now it's active - */ - if (rn) { - rto = RNTORT(rn); - RT_LOCK(rto); - rto->rt_flags |= RTF_UP; - RT_UNLOCK(rto); - } else if (rt->rt_flags & RTF_GATEWAY) { - /* - * For gateway routes, we need to - * make sure that we we are deleting - * the correct gateway. - * rt_mpath_matchgate() does not - * check the case when there is only - * one route in the chain. - */ - if (gateway && - (rt->rt_gateway->sa_len != gateway->sa_len || - memcmp(rt->rt_gateway, gateway, gateway->sa_len))) - senderr(ESRCH); - } - /* - * use the normal delete code to remove - * the first entry - */ - goto normal_rtdel; - } + error = rn_mpath_delete(req, info, rnh, ret_nrt); /* - * if the entry is 2nd and on up + * "bad" holds true for the success case + * as well */ - if (!rt_mpath_deldup(rto, rt)) - panic ("rtrequest1: rt_mpath_deldup"); - RT_LOCK(rt); - RT_ADDREF(rt); - rt->rt_flags &= ~RTF_UP; - goto deldone; /* done with the RTM_DELETE command */ + if (error != ENOENT) + goto bad; } - -normal_rtdel: #endif /* * Remove the item from the tree and return it. @@ -921,9 +964,6 @@ normal_rtdel: if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) ifa->ifa_rtrequest(RTM_DELETE, rt, info); -#ifdef RADIX_MPATH -deldone: -#endif /* * One more rtentry floating around that is not * linked to the routing table. rttrash will be decremented Modified: user/kmacy/HEAD_fast_net/sys/net/route.h ============================================================================== --- user/kmacy/HEAD_fast_net/sys/net/route.h Wed Dec 31 03:02:59 2008 (r186624) +++ user/kmacy/HEAD_fast_net/sys/net/route.h Wed Dec 31 03:13:05 2008 (r186625) @@ -195,7 +195,8 @@ struct ortentry { #define RTF_BROADCAST 0x400000 /* route represents a bcast address */ #define RTF_MULTICAST 0x800000 /* route represents a mcast address */ /* 0x1000000 and up unassigned */ -#define RTF_RNH_LOCKED 0x40000000 /* radix node head locked by caller */ +#define RTF_SHUTDOWN 0x20000000 /* no new connections */ +#define RTF_RNH_LOCKED 0x40000000 /* Mask of RTF flags that are allowed to be modified by RTM_CHANGE. */ #define RTF_FMASK \ @@ -254,6 +255,7 @@ struct rt_msghdr { #define RTM_DELMADDR 0x10 /* mcast group membership being deleted */ #define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */ #define RTM_IEEE80211 0x12 /* IEEE80211 wireless event */ +#define RTM_SHUTDOWN 0x13 /* don't use for new connections */ /* * Bitmask values for rtm_inits and rmx_locks.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812310313.mBV3D5ed013238>