diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/radix.c | 20 | ||||
-rw-r--r-- | sys/net/route.c | 15 |
2 files changed, 29 insertions, 6 deletions
diff --git a/sys/net/radix.c b/sys/net/radix.c index 17773d3..04dc0be 100644 --- a/sys/net/radix.c +++ b/sys/net/radix.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)radix.c 8.2 (Berkeley) 1/4/94 - * $Id: radix.c,v 1.5 1994/10/15 21:33:17 phk Exp $ + * $Id: radix.c,v 1.6 1995/03/20 21:30:12 wollman Exp $ */ /* @@ -684,16 +684,21 @@ rn_walktree_from(h, a, m, f, w) /* * rn_search_m is sort-of-open-coded here. */ + /* printf("about to search\n"); */ for (rn = h->rnh_treetop; rn->rn_b >= 0; ) { last = rn; - if (!(rn->rn_bmask & xm[rn->rn_off])) + /* printf("rn_b %d, rn_bmask %x, xm[rn_off] %x\n", + rn->rn_b, rn->rn_bmask, xm[rn->rn_off]); */ + if (!(rn->rn_bmask & xm[rn->rn_off])) { break; + } if (rn->rn_bmask & xa[rn->rn_off]) { rn = rn->rn_r; } else { rn = rn->rn_l; } } + /* printf("done searching\n"); */ /* * Two cases: either we stepped off the end of our mask, @@ -704,6 +709,8 @@ rn_walktree_from(h, a, m, f, w) rn = last; lastb = rn->rn_b; + /* printf("rn %p, lastb %d\n", rn, lastb);*/ + /* * This gets complicated because we may delete the node * while applying the function f to it, so we need to calculate @@ -713,6 +720,7 @@ rn_walktree_from(h, a, m, f, w) rn = rn->rn_l; while (!stopping) { + /* printf("node %p (%d)\n", rn, rn->rn_b); */ base = rn; /* If at right child go back up, otherwise, go right */ while (rn->rn_p->rn_r == rn && !(rn->rn_flags & RNF_ROOT)) { @@ -721,6 +729,7 @@ rn_walktree_from(h, a, m, f, w) /* if went up beyond last, stop */ if (rn->rn_b < lastb) { stopping = 1; + /* printf("up too far\n"); */ } } @@ -731,11 +740,18 @@ rn_walktree_from(h, a, m, f, w) /* Process leaves */ while ((rn = base) != 0) { base = rn->rn_dupedkey; + /* printf("leaf %p\n", rn); */ if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w))) return (error); } rn = next; + + if (rn->rn_flags & RNF_ROOT) { + /* printf("root, stopping"); */ + stopping = 1; + } + } return 0; } diff --git a/sys/net/route.c b/sys/net/route.c index 9cd58c9..5a770cf 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)route.c 8.2 (Berkeley) 11/15/93 - * $Id: route.c,v 1.18 1995/03/20 23:00:57 davidg Exp $ + * $Id: route.c,v 1.19 1995/03/21 19:50:34 wollman Exp $ */ #include <sys/param.h> @@ -150,7 +150,7 @@ rtfree(rt) rt_tables[rt_key(rt)->sa_family]; register struct ifaddr *ifa; - if (rt == 0) + if (rt == 0 || rnh == 0) panic("rtfree"); rt->rt_refcnt--; if(rnh->rnh_close && rt->rt_refcnt == 0) { @@ -377,16 +377,23 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) panic ("rtrequest delete"); rt = (struct rtentry *)rn; - rt->rt_flags &= ~RTF_UP; /* * Now search what's left of the subtree for any cloned * routes which might have been formed from this node. */ - if (rt->rt_flags & RTF_PRCLONING) { + if ((rt->rt_flags & RTF_PRCLONING) && netmask) { rnh->rnh_walktree_from(rnh, dst, netmask, rt_fixdelete, rt); } + + /* + * NB: RTF_UP must be set during the search above, + * because we might delete the last ref, causing + * rt to get freed prematurely. + */ + rt->rt_flags &= ~RTF_UP; + if (rt->rt_gwroute) { rt = rt->rt_gwroute; RTFREE(rt); (rt = (struct rtentry *)rn)->rt_gwroute = 0; |