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

Reply via email to