svn commit: r185734 - user/kmacy/HEAD_fast_multi_xmit/sys/net
Kip Macy
kmacy at FreeBSD.org
Sat Dec 6 22:00:21 PST 2008
Author: kmacy
Date: Sun Dec 7 06:00:20 2008
New Revision: 185734
URL: http://svn.freebsd.org/changeset/base/185734
Log:
add support for "route shutdown" - allow existing connections to
continue to use the route but no future ones
Modified:
user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c
user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c
user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h
Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c
==============================================================================
--- user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c Sun Dec 7 05:49:22 2008 (r185733)
+++ user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c Sun Dec 7 06:00:20 2008 (r185734)
@@ -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_multi_xmit/sys/net/route.c
==============================================================================
--- user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c Sun Dec 7 05:49:22 2008 (r185733)
+++ user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c Sun Dec 7 06:00:20 2008 (r185734)
@@ -908,6 +908,98 @@ rtrequest1(int req, struct rt_addrinfo *
return (rtrequest1_fib(req, info, ret_nrt, 0));
}
+#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)
@@ -945,65 +1037,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);
+ error = rn_mpath_delete(req, info, rnh, ret_nrt);
/*
- * this is the first entry in the chain
+ * "bad" holds true for the success case
+ * as well
*/
- 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;
- }
- /*
- * if the entry is 2nd and on up
- */
- 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.
@@ -1044,9 +1087,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_multi_xmit/sys/net/route.h
==============================================================================
--- user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h Sun Dec 7 05:49:22 2008 (r185733)
+++ user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h Sun Dec 7 06:00:20 2008 (r185734)
@@ -197,7 +197,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
+#define RTF_SHUTDOWN 0x20000000 /* no new connections */
+#define RTF_RNH_LOCKED 0x40000000
#define RTF_DESTEN_VALID 0x80000000 /* rtentry_info L2 addr is valid */
/* Mask of RTF flags that are allowed to be modified by RTM_CHANGE. */
@@ -257,6 +258,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.
More information about the svn-src-user
mailing list