summaryrefslogtreecommitdiffstats
path: root/sys/net/route.c
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2006-06-05 21:20:21 +0000
committerqingli <qingli@FreeBSD.org>2006-06-05 21:20:21 +0000
commitee8156b6fd83f88c6c4b81ce9c8ed81f03d3e796 (patch)
tree0ed2f6a6f32a6fa3cccb8edd09e6743e7ab4e33a /sys/net/route.c
parent280370a7dad3c18a14bdf5c30359d73f8c68695e (diff)
downloadFreeBSD-src-ee8156b6fd83f88c6c4b81ce9c8ed81f03d3e796.zip
FreeBSD-src-ee8156b6fd83f88c6c4b81ce9c8ed81f03d3e796.tar.gz
Assuming the interface has an address of x.x.x.195, a mask of
255.255.255.0, and a default route with gateway x.x.x.1. Now if the address mask is changed to something more specific, e.g., 255.255.255.128, then after the mask change the default gateway is no longer reachable. Since the default route is still present in the routing table, when the output code tries to resolve the address of the default gateway in function rt_check(), again, the default route will be returned by rtalloc1(). Because the lock is currently held on the rtentry structure, one more attempt to hold the lock will trigger a crash due to "lock recursed on non-recursive mutex ..." This is a general problem. The fix checks for the above condition so that an existing route entry is not mistaken for a new cloned route. Approriately, an ENETUNREACH error is returned back to the caller Approved by: andre
Diffstat (limited to 'sys/net/route.c')
-rw-r--r--sys/net/route.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 0e1085a..adb28a0 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1309,6 +1309,12 @@ rt_check(struct rtentry **lrt, struct rtentry **lrt0, struct sockaddr *dst)
lookup:
RT_UNLOCK(rt0);
rt = rtalloc1(rt->rt_gateway, 1, 0UL);
+ if (rt == rt0) {
+ rt0->rt_gwroute = NULL;
+ RT_REMREF(rt0);
+ RT_UNLOCK(rt0);
+ senderr(ENETUNREACH);
+ }
RT_LOCK(rt0);
rt0->rt_gwroute = rt;
if (rt == NULL) {
OpenPOWER on IntegriCloud