diff options
author | glebius <glebius@FreeBSD.org> | 2005-08-11 08:14:53 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-08-11 08:14:53 +0000 |
commit | fa253399af72f4968a7eddd5210066700b92d2c0 (patch) | |
tree | decf2e9a9a44b246a6d6dd15b016ed79b3b91a61 /sys/net/route.c | |
parent | e0688f129366b4f89acf47c45af55135dc0609ae (diff) | |
download | FreeBSD-src-fa253399af72f4968a7eddd5210066700b92d2c0.zip FreeBSD-src-fa253399af72f4968a7eddd5210066700b92d2c0.tar.gz |
o Make rt_check() function more strict:
- rt0 passed to rt_check() must not be NULL, assert this.
- rt returned by rt_check() must be valid locked rtentry,
if no error occured.
o Modify callers, so that they never pass NULL rt0
to rt_check().
Reviewed by: sam, ume (nd6.c)
Diffstat (limited to 'sys/net/route.c')
-rw-r--r-- | sys/net/route.c | 80 |
1 files changed, 40 insertions, 40 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index 51b2631..126d69a 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1262,51 +1262,51 @@ rt_check(struct rtentry **lrt, struct rtentry **lrt0, struct sockaddr *dst) struct rtentry *rt0; int error; - rt0 = *lrt0; - rt = rt0; - if (rt) { - /* NB: the locking here is tortuous... */ - RT_LOCK(rt); + KASSERT(*lrt0 != NULL, ("rt_check")); + rt = rt0 = *lrt0; + + /* NB: the locking here is tortuous... */ + RT_LOCK(rt); + if ((rt->rt_flags & RTF_UP) == 0) { + RT_UNLOCK(rt); + rt = rtalloc1(dst, 1, 0UL); + if (rt != NULL) { + RT_REMREF(rt); + /* XXX what about if change? */ + } else + senderr(EHOSTUNREACH); + rt0 = rt; + } + /* XXX BSD/OS checks dst->sa_family != AF_NS */ + if (rt->rt_flags & RTF_GATEWAY) { + if (rt->rt_gwroute == NULL) + goto lookup; + rt = rt->rt_gwroute; + RT_LOCK(rt); /* NB: gwroute */ if ((rt->rt_flags & RTF_UP) == 0) { - RT_UNLOCK(rt); - rt = rtalloc1(dst, 1, 0UL); - if (rt != NULL) { - RT_REMREF(rt); - /* XXX what about if change? */ - } else - senderr(EHOSTUNREACH); - rt0 = rt; - } - /* XXX BSD/OS checks dst->sa_family != AF_NS */ - if (rt->rt_flags & RTF_GATEWAY) { - if (rt->rt_gwroute == NULL) - goto lookup; - rt = rt->rt_gwroute; - RT_LOCK(rt); /* NB: gwroute */ - if ((rt->rt_flags & RTF_UP) == 0) { - rtfree(rt); /* unlock gwroute */ - rt = rt0; - lookup: + rtfree(rt); /* unlock gwroute */ + rt = rt0; + lookup: + RT_UNLOCK(rt0); + rt = rtalloc1(rt->rt_gateway, 1, 0UL); + RT_LOCK(rt0); + rt0->rt_gwroute = rt; + if (rt == NULL) { RT_UNLOCK(rt0); - rt = rtalloc1(rt->rt_gateway, 1, 0UL); - RT_LOCK(rt0); - rt0->rt_gwroute = rt; - if (rt == NULL) { - RT_UNLOCK(rt0); - senderr(EHOSTUNREACH); - } + senderr(EHOSTUNREACH); } - RT_UNLOCK(rt0); - } - /* XXX why are we inspecting rmx_expire? */ - error = (rt->rt_flags & RTF_REJECT) && - (rt->rt_rmx.rmx_expire == 0 || - time_second < rt->rt_rmx.rmx_expire); - if (error) { - RT_UNLOCK(rt); - senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } + RT_UNLOCK(rt0); } + /* XXX why are we inspecting rmx_expire? */ + error = (rt->rt_flags & RTF_REJECT) && + (rt->rt_rmx.rmx_expire == 0 || + time_second < rt->rt_rmx.rmx_expire); + if (error) { + RT_UNLOCK(rt); + senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); + } + *lrt = rt; *lrt0 = rt0; return (0); |