aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorQing Li <qingli@FreeBSD.org>2010-04-02 05:02:50 +0000
committerQing Li <qingli@FreeBSD.org>2010-04-02 05:02:50 +0000
commitc951da56b4f19a637c7fdf734fc500560a9555de (patch)
treea67d7828eb0348202e91d50a0581743b1596f635 /sys/net
parentca2d42b2a1bb8cefb1c2bf163b67a0f2a062d4b2 (diff)
Notes
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/flowtable.c3
-rw-r--r--sys/net/radix.c2
-rw-r--r--sys/net/radix_mpath.c3
-rw-r--r--sys/net/route.c38
-rw-r--r--sys/net/route.h2
5 files changed, 38 insertions, 10 deletions
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index 0ad8a66788cd..39b6b40a996d 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -870,7 +870,8 @@ flow_stale(struct flowtable *ft, struct flentry *fle)
|| ((fle->f_rt->rt_flags & RTF_HOST) &&
((fle->f_rt->rt_flags & (RTF_UP))
!= (RTF_UP)))
- || (fle->f_rt->rt_ifp == NULL))
+ || (fle->f_rt->rt_ifp == NULL)
+ || !RT_LINK_IS_UP(fle->f_rt->rt_ifp))
return (1);
idle_time = time_uptime - fle->f_uptime;
diff --git a/sys/net/radix.c b/sys/net/radix.c
index 9f2383d7c7cf..33fcf828a240 100644
--- a/sys/net/radix.c
+++ b/sys/net/radix.c
@@ -761,8 +761,10 @@ on2:
if (m->rm_flags & RNF_NORMAL) {
mmask = m->rm_leaf->rn_mask;
if (tt->rn_flags & RNF_NORMAL) {
+#if !defined(RADIX_MPATH)
log(LOG_ERR,
"Non-unique normal route, mask not entered\n");
+#endif
return tt;
}
} else
diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c
index 9be01d2fe3c3..ea84e5ce2282 100644
--- a/sys/net/radix_mpath.c
+++ b/sys/net/radix_mpath.c
@@ -270,7 +270,8 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
* XXX we don't attempt to lookup cached route again; what should
* be done for sendto(3) case?
*/
- if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
+ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)
+ && RT_LINK_IS_UP(ro->ro_rt->rt_ifp))
return;
ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum);
diff --git a/sys/net/route.c b/sys/net/route.c
index a938c9c1b7fb..e500ed13033a 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -830,7 +830,13 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
int
rtexpunge(struct rtentry *rt)
{
+#if !defined(RADIX_MPATH)
struct radix_node *rn;
+#else
+ struct rt_addrinfo info;
+ int fib;
+ struct rtentry *rt0;
+#endif
struct radix_node_head *rnh;
struct ifaddr *ifa;
int error = 0;
@@ -843,14 +849,26 @@ rtexpunge(struct rtentry *rt)
if (rnh == NULL)
return (EAFNOSUPPORT);
RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
-#if 0
- /*
- * We cannot assume anything about the reference count
- * because protocols call us in many situations; often
- * before unwinding references to the table entry.
- */
- KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt));
-#endif
+
+#ifdef RADIX_MPATH
+ fib = rt->rt_fibnum;
+ bzero(&info, sizeof(info));
+ info.rti_ifp = rt->rt_ifp;
+ info.rti_flags = RTF_RNH_LOCKED;
+ info.rti_info[RTAX_DST] = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_ifa->ifa_addr;
+
+ RT_UNLOCK(rt);
+ error = rtrequest1_fib(RTM_DELETE, &info, &rt0, fib);
+
+ if (error == 0 && rt0 != NULL) {
+ rt = rt0;
+ RT_LOCK(rt);
+ } else if (error != 0) {
+ RT_LOCK(rt);
+ return (error);
+ }
+#else
/*
* Remove the item from the tree; it should be there,
* but when callers invoke us blindly it may not (sigh).
@@ -864,6 +882,7 @@ rtexpunge(struct rtentry *rt)
("unexpected flags 0x%x", rn->rn_flags));
KASSERT(rt == RNTORT(rn),
("lookup mismatch, rt %p rn %p", rt, rn));
+#endif /* RADIX_MPATH */
rt->rt_flags &= ~RTF_UP;
@@ -886,7 +905,9 @@ rtexpunge(struct rtentry *rt)
* linked to the routing table.
*/
V_rttrash++;
+#if !defined(RADIX_MPATH)
bad:
+#endif
return (error);
}
@@ -1044,6 +1065,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
*/
if (error != ENOENT)
goto bad;
+ error = 0;
}
#endif
/*
diff --git a/sys/net/route.h b/sys/net/route.h
index 4cf8a816466f..6857cb3473dd 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -319,6 +319,8 @@ struct rt_addrinfo {
#ifdef _KERNEL
+#define RT_LINK_IS_UP(ifp) ((ifp)->if_link_state == LINK_STATE_UP)
+
#define RT_LOCK_INIT(_rt) \
mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK)
#define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx)