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)
This commit is contained in:
glebius 2005-08-11 08:14:53 +00:00
parent e0688f1293
commit fa253399af
5 changed files with 71 additions and 59 deletions

View File

@ -152,14 +152,16 @@ atm_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
case AF_INET:
case AF_INET6:
{
struct rtentry *rt;
struct rtentry *rt = NULL;
/*
* check route
*/
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
if (rt0 != NULL) {
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
}
if (dst->sa_family == AF_INET6)
etype = ETHERTYPE_IPV6;

View File

@ -81,7 +81,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
{
struct fw_com *fc = IFP2FC(ifp);
int error, type;
struct rtentry *rt;
struct rtentry *rt = NULL;
struct m_tag *mtag;
union fw_encap *enc;
struct fw_hwaddr *destfw;
@ -103,10 +103,12 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
goto bad;
}
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
if (rt0 != NULL) {
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
}
/*
* For unicast, we make a tag to store the lladdr of the

View File

@ -243,7 +243,7 @@ iso88025_output(ifp, m, dst, rt0)
struct iso88025_header *th;
struct iso88025_header gen_th;
struct sockaddr_dl *sdl = NULL;
struct rtentry *rt;
struct rtentry *rt = NULL;
#ifdef MAC
error = mac_check_ifnet_transmit(ifp, m);
@ -260,10 +260,12 @@ iso88025_output(ifp, m, dst, rt0)
/* Calculate routing info length based on arp table entry */
/* XXX any better way to do this ? */
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
if (rt0 != NULL) {
error = rt_check(&rt, &rt0, dst);
if (error)
goto bad;
RT_UNLOCK(rt);
}
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway))
if (SDL_ISO88025(sdl)->trld_rcf != 0)

View File

@ -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);
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:
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);
}
}
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);
}
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) {
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);
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);
}
*lrt = rt;
*lrt0 = rt0;
return (0);

View File

@ -2065,6 +2065,12 @@ nd6_storelladdr(ifp, rt0, m, dst, desten)
}
}
if (rt0 == NULL) {
/* this could happen, if we could not allocate memory */
m_freem(m);
return (ENOMEM);
}
error = rt_check(&rt, &rt0, dst);
if (error) {
m_freem(m);