Hello everyone, you were right, it was broken. rt_if_remove_rtdelete was looking in wrong domain and the right one contained freed stuff. I'm not sure whether what I've done is correct and even less sure about what struct ifnet's if_rdomain is for. Can someone clarify this for me? (or through some manual page)
This diffs works (tabs are likely to be replaced by spaces), however it seems like a workaround for me. ================================================== --- route.c Fri May 21 14:18:08 2010 +++ /usr/src/sys/net/route.c Fri May 21 14:29:13 2010 @@ -1415,17 +1415,30 @@ void rt_if_remove(struct ifnet *ifp) { int i; - u_int tid; + u_int tid, orig_rdomain = ifp->if_rdomain; struct radix_node_head *rnh; for (tid = 0; tid <= rtbl_id_max; tid++) { for (i = 1; i <= AF_MAX; i++) { if ((rnh = rt_gettable(i, tid)) != NULL) + { + /* XXX: This is an ugly thing + * cos I couldn't find the proper meaning + * of the "rdomain" field in struct + * describing interface potentially present + * in more routing domains. + * rt_if_remove_rtdelete wants it + * this fn restores it back + * but is this really necessary? + */ + ifp->if_rdomain = tid; while ((*rnh->rnh_walktree)(rnh, rt_if_remove_rtdelete, ifp) == EAGAIN) ; /* nothing */ + } } } + ifp->if_rdomain = orig_rdomain; } /* @@ -1443,7 +1456,7 @@ rt_if_remove_rtdelete(struct radix_node *rn, void *vif if (rt->rt_ifp == ifp) { int cloning = (rt->rt_flags & RTF_CLONING); - if (rtdeletemsg(rt, ifp->if_rdomain /* XXX wrong */) == 0 && cloning) + if (rtdeletemsg(rt, ifp->if_rdomain /* XXX wrong ?? */) == 0 && cloning) return (EAGAIN); } ================================================== -- Martin Pelikan